vulkan_wrapper.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930
  1. // Copyright 2020 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <algorithm>
  5. #include <exception>
  6. #include <memory>
  7. #include <optional>
  8. #include <string_view>
  9. #include <utility>
  10. #include <vector>
  11. #include "common/common_types.h"
  12. #include "common/logging/log.h"
  13. #include "video_core/vulkan_common/vulkan_wrapper.h"
  14. namespace Vulkan::vk {
  15. namespace {
  16. template <typename Func>
  17. void SortPhysicalDevices(std::vector<VkPhysicalDevice>& devices, const InstanceDispatch& dld,
  18. Func&& func) {
  19. // Calling GetProperties calls Vulkan more than needed. But they are supposed to be cheap
  20. // functions.
  21. std::stable_sort(devices.begin(), devices.end(),
  22. [&dld, &func](VkPhysicalDevice lhs, VkPhysicalDevice rhs) {
  23. return func(vk::PhysicalDevice(lhs, dld).GetProperties(),
  24. vk::PhysicalDevice(rhs, dld).GetProperties());
  25. });
  26. }
  27. void SortPhysicalDevicesPerVendor(std::vector<VkPhysicalDevice>& devices,
  28. const InstanceDispatch& dld,
  29. std::initializer_list<u32> vendor_ids) {
  30. for (auto it = vendor_ids.end(); it != vendor_ids.begin();) {
  31. --it;
  32. SortPhysicalDevices(devices, dld, [id = *it](const auto& lhs, const auto& rhs) {
  33. return lhs.vendorID == id && rhs.vendorID != id;
  34. });
  35. }
  36. }
  37. void SortPhysicalDevices(std::vector<VkPhysicalDevice>& devices, const InstanceDispatch& dld) {
  38. // Sort by name, this will set a base and make GPUs with higher numbers appear first
  39. // (e.g. GTX 1650 will intentionally be listed before a GTX 1080).
  40. SortPhysicalDevices(devices, dld, [](const auto& lhs, const auto& rhs) {
  41. return std::string_view{lhs.deviceName} > std::string_view{rhs.deviceName};
  42. });
  43. // Prefer discrete over non-discrete
  44. SortPhysicalDevices(devices, dld, [](const auto& lhs, const auto& rhs) {
  45. return lhs.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU &&
  46. rhs.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
  47. });
  48. // Prefer Nvidia over AMD, AMD over Intel, Intel over the rest.
  49. SortPhysicalDevicesPerVendor(devices, dld, {0x10DE, 0x1002, 0x8086});
  50. }
  51. template <typename T>
  52. bool Proc(T& result, const InstanceDispatch& dld, const char* proc_name,
  53. VkInstance instance = nullptr) noexcept {
  54. result = reinterpret_cast<T>(dld.vkGetInstanceProcAddr(instance, proc_name));
  55. return result != nullptr;
  56. }
  57. template <typename T>
  58. void Proc(T& result, const DeviceDispatch& dld, const char* proc_name, VkDevice device) noexcept {
  59. result = reinterpret_cast<T>(dld.vkGetDeviceProcAddr(device, proc_name));
  60. }
  61. void Load(VkDevice device, DeviceDispatch& dld) noexcept {
  62. #define X(name) Proc(dld.name, dld, #name, device)
  63. X(vkAcquireNextImageKHR);
  64. X(vkAllocateCommandBuffers);
  65. X(vkAllocateDescriptorSets);
  66. X(vkAllocateMemory);
  67. X(vkBeginCommandBuffer);
  68. X(vkBindBufferMemory);
  69. X(vkBindImageMemory);
  70. X(vkCmdBeginQuery);
  71. X(vkCmdBeginRenderPass);
  72. X(vkCmdBeginTransformFeedbackEXT);
  73. X(vkCmdBeginDebugUtilsLabelEXT);
  74. X(vkCmdBindDescriptorSets);
  75. X(vkCmdBindIndexBuffer);
  76. X(vkCmdBindPipeline);
  77. X(vkCmdBindTransformFeedbackBuffersEXT);
  78. X(vkCmdBindVertexBuffers);
  79. X(vkCmdBlitImage);
  80. X(vkCmdClearAttachments);
  81. X(vkCmdCopyBuffer);
  82. X(vkCmdCopyBufferToImage);
  83. X(vkCmdCopyImage);
  84. X(vkCmdCopyImageToBuffer);
  85. X(vkCmdDispatch);
  86. X(vkCmdDraw);
  87. X(vkCmdDrawIndexed);
  88. X(vkCmdEndQuery);
  89. X(vkCmdEndRenderPass);
  90. X(vkCmdEndTransformFeedbackEXT);
  91. X(vkCmdEndDebugUtilsLabelEXT);
  92. X(vkCmdFillBuffer);
  93. X(vkCmdPipelineBarrier);
  94. X(vkCmdPushConstants);
  95. X(vkCmdSetBlendConstants);
  96. X(vkCmdSetDepthBias);
  97. X(vkCmdSetDepthBounds);
  98. X(vkCmdSetEvent);
  99. X(vkCmdSetScissor);
  100. X(vkCmdSetStencilCompareMask);
  101. X(vkCmdSetStencilReference);
  102. X(vkCmdSetStencilWriteMask);
  103. X(vkCmdSetViewport);
  104. X(vkCmdWaitEvents);
  105. X(vkCmdBindVertexBuffers2EXT);
  106. X(vkCmdSetCullModeEXT);
  107. X(vkCmdSetDepthBoundsTestEnableEXT);
  108. X(vkCmdSetDepthCompareOpEXT);
  109. X(vkCmdSetDepthTestEnableEXT);
  110. X(vkCmdSetDepthWriteEnableEXT);
  111. X(vkCmdSetFrontFaceEXT);
  112. X(vkCmdSetPrimitiveTopologyEXT);
  113. X(vkCmdSetStencilOpEXT);
  114. X(vkCmdSetStencilTestEnableEXT);
  115. X(vkCmdResolveImage);
  116. X(vkCreateBuffer);
  117. X(vkCreateBufferView);
  118. X(vkCreateCommandPool);
  119. X(vkCreateComputePipelines);
  120. X(vkCreateDescriptorPool);
  121. X(vkCreateDescriptorSetLayout);
  122. X(vkCreateDescriptorUpdateTemplateKHR);
  123. X(vkCreateEvent);
  124. X(vkCreateFence);
  125. X(vkCreateFramebuffer);
  126. X(vkCreateGraphicsPipelines);
  127. X(vkCreateImage);
  128. X(vkCreateImageView);
  129. X(vkCreatePipelineLayout);
  130. X(vkCreateQueryPool);
  131. X(vkCreateRenderPass);
  132. X(vkCreateSampler);
  133. X(vkCreateSemaphore);
  134. X(vkCreateShaderModule);
  135. X(vkCreateSwapchainKHR);
  136. X(vkDestroyBuffer);
  137. X(vkDestroyBufferView);
  138. X(vkDestroyCommandPool);
  139. X(vkDestroyDescriptorPool);
  140. X(vkDestroyDescriptorSetLayout);
  141. X(vkDestroyDescriptorUpdateTemplateKHR);
  142. X(vkDestroyEvent);
  143. X(vkDestroyFence);
  144. X(vkDestroyFramebuffer);
  145. X(vkDestroyImage);
  146. X(vkDestroyImageView);
  147. X(vkDestroyPipeline);
  148. X(vkDestroyPipelineLayout);
  149. X(vkDestroyQueryPool);
  150. X(vkDestroyRenderPass);
  151. X(vkDestroySampler);
  152. X(vkDestroySemaphore);
  153. X(vkDestroyShaderModule);
  154. X(vkDestroySwapchainKHR);
  155. X(vkDeviceWaitIdle);
  156. X(vkEndCommandBuffer);
  157. X(vkFreeCommandBuffers);
  158. X(vkFreeDescriptorSets);
  159. X(vkFreeMemory);
  160. X(vkGetBufferMemoryRequirements);
  161. X(vkGetDeviceQueue);
  162. X(vkGetEventStatus);
  163. X(vkGetFenceStatus);
  164. X(vkGetImageMemoryRequirements);
  165. X(vkGetMemoryFdKHR);
  166. #ifdef _WIN32
  167. X(vkGetMemoryWin32HandleKHR);
  168. #endif
  169. X(vkGetQueryPoolResults);
  170. X(vkGetSemaphoreCounterValueKHR);
  171. X(vkMapMemory);
  172. X(vkQueueSubmit);
  173. X(vkResetFences);
  174. X(vkResetQueryPoolEXT);
  175. X(vkSetDebugUtilsObjectNameEXT);
  176. X(vkSetDebugUtilsObjectTagEXT);
  177. X(vkUnmapMemory);
  178. X(vkUpdateDescriptorSetWithTemplateKHR);
  179. X(vkUpdateDescriptorSets);
  180. X(vkWaitForFences);
  181. X(vkWaitSemaphoresKHR);
  182. #undef X
  183. }
  184. template <typename T>
  185. void SetObjectName(const DeviceDispatch* dld, VkDevice device, T handle, VkObjectType type,
  186. const char* name) {
  187. const VkDebugUtilsObjectNameInfoEXT name_info{
  188. .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
  189. .pNext = nullptr,
  190. .objectType = VK_OBJECT_TYPE_IMAGE,
  191. .objectHandle = reinterpret_cast<u64>(handle),
  192. .pObjectName = name,
  193. };
  194. Check(dld->vkSetDebugUtilsObjectNameEXT(device, &name_info));
  195. }
  196. } // Anonymous namespace
  197. bool Load(InstanceDispatch& dld) noexcept {
  198. #define X(name) Proc(dld.name, dld, #name)
  199. return X(vkCreateInstance) && X(vkEnumerateInstanceExtensionProperties) &&
  200. X(vkEnumerateInstanceLayerProperties);
  201. #undef X
  202. }
  203. bool Load(VkInstance instance, InstanceDispatch& dld) noexcept {
  204. #define X(name) Proc(dld.name, dld, #name, instance)
  205. // These functions may fail to load depending on the enabled extensions.
  206. // Don't return a failure on these.
  207. X(vkCreateDebugUtilsMessengerEXT);
  208. X(vkDestroyDebugUtilsMessengerEXT);
  209. X(vkDestroySurfaceKHR);
  210. X(vkGetPhysicalDeviceFeatures2KHR);
  211. X(vkGetPhysicalDeviceProperties2KHR);
  212. X(vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
  213. X(vkGetPhysicalDeviceSurfaceFormatsKHR);
  214. X(vkGetPhysicalDeviceSurfacePresentModesKHR);
  215. X(vkGetPhysicalDeviceSurfaceSupportKHR);
  216. X(vkGetSwapchainImagesKHR);
  217. X(vkQueuePresentKHR);
  218. return X(vkCreateDevice) && X(vkDestroyDevice) && X(vkDestroyDevice) &&
  219. X(vkEnumerateDeviceExtensionProperties) && X(vkEnumeratePhysicalDevices) &&
  220. X(vkGetDeviceProcAddr) && X(vkGetPhysicalDeviceFormatProperties) &&
  221. X(vkGetPhysicalDeviceMemoryProperties) && X(vkGetPhysicalDeviceProperties) &&
  222. X(vkGetPhysicalDeviceQueueFamilyProperties);
  223. #undef X
  224. }
  225. const char* Exception::what() const noexcept {
  226. return ToString(result);
  227. }
  228. const char* ToString(VkResult result) noexcept {
  229. switch (result) {
  230. case VkResult::VK_SUCCESS:
  231. return "VK_SUCCESS";
  232. case VkResult::VK_NOT_READY:
  233. return "VK_NOT_READY";
  234. case VkResult::VK_TIMEOUT:
  235. return "VK_TIMEOUT";
  236. case VkResult::VK_EVENT_SET:
  237. return "VK_EVENT_SET";
  238. case VkResult::VK_EVENT_RESET:
  239. return "VK_EVENT_RESET";
  240. case VkResult::VK_INCOMPLETE:
  241. return "VK_INCOMPLETE";
  242. case VkResult::VK_ERROR_OUT_OF_HOST_MEMORY:
  243. return "VK_ERROR_OUT_OF_HOST_MEMORY";
  244. case VkResult::VK_ERROR_OUT_OF_DEVICE_MEMORY:
  245. return "VK_ERROR_OUT_OF_DEVICE_MEMORY";
  246. case VkResult::VK_ERROR_INITIALIZATION_FAILED:
  247. return "VK_ERROR_INITIALIZATION_FAILED";
  248. case VkResult::VK_ERROR_DEVICE_LOST:
  249. return "VK_ERROR_DEVICE_LOST";
  250. case VkResult::VK_ERROR_MEMORY_MAP_FAILED:
  251. return "VK_ERROR_MEMORY_MAP_FAILED";
  252. case VkResult::VK_ERROR_LAYER_NOT_PRESENT:
  253. return "VK_ERROR_LAYER_NOT_PRESENT";
  254. case VkResult::VK_ERROR_EXTENSION_NOT_PRESENT:
  255. return "VK_ERROR_EXTENSION_NOT_PRESENT";
  256. case VkResult::VK_ERROR_FEATURE_NOT_PRESENT:
  257. return "VK_ERROR_FEATURE_NOT_PRESENT";
  258. case VkResult::VK_ERROR_INCOMPATIBLE_DRIVER:
  259. return "VK_ERROR_INCOMPATIBLE_DRIVER";
  260. case VkResult::VK_ERROR_TOO_MANY_OBJECTS:
  261. return "VK_ERROR_TOO_MANY_OBJECTS";
  262. case VkResult::VK_ERROR_FORMAT_NOT_SUPPORTED:
  263. return "VK_ERROR_FORMAT_NOT_SUPPORTED";
  264. case VkResult::VK_ERROR_FRAGMENTED_POOL:
  265. return "VK_ERROR_FRAGMENTED_POOL";
  266. case VkResult::VK_ERROR_OUT_OF_POOL_MEMORY:
  267. return "VK_ERROR_OUT_OF_POOL_MEMORY";
  268. case VkResult::VK_ERROR_INVALID_EXTERNAL_HANDLE:
  269. return "VK_ERROR_INVALID_EXTERNAL_HANDLE";
  270. case VkResult::VK_ERROR_SURFACE_LOST_KHR:
  271. return "VK_ERROR_SURFACE_LOST_KHR";
  272. case VkResult::VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
  273. return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR";
  274. case VkResult::VK_SUBOPTIMAL_KHR:
  275. return "VK_SUBOPTIMAL_KHR";
  276. case VkResult::VK_ERROR_OUT_OF_DATE_KHR:
  277. return "VK_ERROR_OUT_OF_DATE_KHR";
  278. case VkResult::VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
  279. return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR";
  280. case VkResult::VK_ERROR_VALIDATION_FAILED_EXT:
  281. return "VK_ERROR_VALIDATION_FAILED_EXT";
  282. case VkResult::VK_ERROR_INVALID_SHADER_NV:
  283. return "VK_ERROR_INVALID_SHADER_NV";
  284. case VkResult::VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT:
  285. return "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT";
  286. case VkResult::VK_ERROR_FRAGMENTATION_EXT:
  287. return "VK_ERROR_FRAGMENTATION_EXT";
  288. case VkResult::VK_ERROR_NOT_PERMITTED_EXT:
  289. return "VK_ERROR_NOT_PERMITTED_EXT";
  290. case VkResult::VK_ERROR_INVALID_DEVICE_ADDRESS_EXT:
  291. return "VK_ERROR_INVALID_DEVICE_ADDRESS_EXT";
  292. case VkResult::VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT:
  293. return "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT";
  294. case VkResult::VK_ERROR_UNKNOWN:
  295. return "VK_ERROR_UNKNOWN";
  296. case VkResult::VK_ERROR_INCOMPATIBLE_VERSION_KHR:
  297. return "VK_ERROR_INCOMPATIBLE_VERSION_KHR";
  298. case VkResult::VK_THREAD_IDLE_KHR:
  299. return "VK_THREAD_IDLE_KHR";
  300. case VkResult::VK_THREAD_DONE_KHR:
  301. return "VK_THREAD_DONE_KHR";
  302. case VkResult::VK_OPERATION_DEFERRED_KHR:
  303. return "VK_OPERATION_DEFERRED_KHR";
  304. case VkResult::VK_OPERATION_NOT_DEFERRED_KHR:
  305. return "VK_OPERATION_NOT_DEFERRED_KHR";
  306. case VkResult::VK_PIPELINE_COMPILE_REQUIRED_EXT:
  307. return "VK_PIPELINE_COMPILE_REQUIRED_EXT";
  308. case VkResult::VK_RESULT_MAX_ENUM:
  309. return "VK_RESULT_MAX_ENUM";
  310. }
  311. return "Unknown";
  312. }
  313. void Destroy(VkInstance instance, const InstanceDispatch& dld) noexcept {
  314. dld.vkDestroyInstance(instance, nullptr);
  315. }
  316. void Destroy(VkDevice device, const InstanceDispatch& dld) noexcept {
  317. dld.vkDestroyDevice(device, nullptr);
  318. }
  319. void Destroy(VkDevice device, VkBuffer handle, const DeviceDispatch& dld) noexcept {
  320. dld.vkDestroyBuffer(device, handle, nullptr);
  321. }
  322. void Destroy(VkDevice device, VkBufferView handle, const DeviceDispatch& dld) noexcept {
  323. dld.vkDestroyBufferView(device, handle, nullptr);
  324. }
  325. void Destroy(VkDevice device, VkCommandPool handle, const DeviceDispatch& dld) noexcept {
  326. dld.vkDestroyCommandPool(device, handle, nullptr);
  327. }
  328. void Destroy(VkDevice device, VkDescriptorPool handle, const DeviceDispatch& dld) noexcept {
  329. dld.vkDestroyDescriptorPool(device, handle, nullptr);
  330. }
  331. void Destroy(VkDevice device, VkDescriptorSetLayout handle, const DeviceDispatch& dld) noexcept {
  332. dld.vkDestroyDescriptorSetLayout(device, handle, nullptr);
  333. }
  334. void Destroy(VkDevice device, VkDescriptorUpdateTemplateKHR handle,
  335. const DeviceDispatch& dld) noexcept {
  336. dld.vkDestroyDescriptorUpdateTemplateKHR(device, handle, nullptr);
  337. }
  338. void Destroy(VkDevice device, VkDeviceMemory handle, const DeviceDispatch& dld) noexcept {
  339. dld.vkFreeMemory(device, handle, nullptr);
  340. }
  341. void Destroy(VkDevice device, VkEvent handle, const DeviceDispatch& dld) noexcept {
  342. dld.vkDestroyEvent(device, handle, nullptr);
  343. }
  344. void Destroy(VkDevice device, VkFence handle, const DeviceDispatch& dld) noexcept {
  345. dld.vkDestroyFence(device, handle, nullptr);
  346. }
  347. void Destroy(VkDevice device, VkFramebuffer handle, const DeviceDispatch& dld) noexcept {
  348. dld.vkDestroyFramebuffer(device, handle, nullptr);
  349. }
  350. void Destroy(VkDevice device, VkImage handle, const DeviceDispatch& dld) noexcept {
  351. dld.vkDestroyImage(device, handle, nullptr);
  352. }
  353. void Destroy(VkDevice device, VkImageView handle, const DeviceDispatch& dld) noexcept {
  354. dld.vkDestroyImageView(device, handle, nullptr);
  355. }
  356. void Destroy(VkDevice device, VkPipeline handle, const DeviceDispatch& dld) noexcept {
  357. dld.vkDestroyPipeline(device, handle, nullptr);
  358. }
  359. void Destroy(VkDevice device, VkPipelineLayout handle, const DeviceDispatch& dld) noexcept {
  360. dld.vkDestroyPipelineLayout(device, handle, nullptr);
  361. }
  362. void Destroy(VkDevice device, VkQueryPool handle, const DeviceDispatch& dld) noexcept {
  363. dld.vkDestroyQueryPool(device, handle, nullptr);
  364. }
  365. void Destroy(VkDevice device, VkRenderPass handle, const DeviceDispatch& dld) noexcept {
  366. dld.vkDestroyRenderPass(device, handle, nullptr);
  367. }
  368. void Destroy(VkDevice device, VkSampler handle, const DeviceDispatch& dld) noexcept {
  369. dld.vkDestroySampler(device, handle, nullptr);
  370. }
  371. void Destroy(VkDevice device, VkSwapchainKHR handle, const DeviceDispatch& dld) noexcept {
  372. dld.vkDestroySwapchainKHR(device, handle, nullptr);
  373. }
  374. void Destroy(VkDevice device, VkSemaphore handle, const DeviceDispatch& dld) noexcept {
  375. dld.vkDestroySemaphore(device, handle, nullptr);
  376. }
  377. void Destroy(VkDevice device, VkShaderModule handle, const DeviceDispatch& dld) noexcept {
  378. dld.vkDestroyShaderModule(device, handle, nullptr);
  379. }
  380. void Destroy(VkInstance instance, VkDebugUtilsMessengerEXT handle,
  381. const InstanceDispatch& dld) noexcept {
  382. dld.vkDestroyDebugUtilsMessengerEXT(instance, handle, nullptr);
  383. }
  384. void Destroy(VkInstance instance, VkSurfaceKHR handle, const InstanceDispatch& dld) noexcept {
  385. dld.vkDestroySurfaceKHR(instance, handle, nullptr);
  386. }
  387. VkResult Free(VkDevice device, VkDescriptorPool handle, Span<VkDescriptorSet> sets,
  388. const DeviceDispatch& dld) noexcept {
  389. return dld.vkFreeDescriptorSets(device, handle, sets.size(), sets.data());
  390. }
  391. VkResult Free(VkDevice device, VkCommandPool handle, Span<VkCommandBuffer> buffers,
  392. const DeviceDispatch& dld) noexcept {
  393. dld.vkFreeCommandBuffers(device, handle, buffers.size(), buffers.data());
  394. return VK_SUCCESS;
  395. }
  396. Instance Instance::Create(u32 version, Span<const char*> layers, Span<const char*> extensions,
  397. InstanceDispatch& dispatch) {
  398. const VkApplicationInfo application_info{
  399. .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
  400. .pNext = nullptr,
  401. .pApplicationName = "yuzu Emulator",
  402. .applicationVersion = VK_MAKE_VERSION(0, 1, 0),
  403. .pEngineName = "yuzu Emulator",
  404. .engineVersion = VK_MAKE_VERSION(0, 1, 0),
  405. .apiVersion = version,
  406. };
  407. const VkInstanceCreateInfo ci{
  408. .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
  409. .pNext = nullptr,
  410. .flags = 0,
  411. .pApplicationInfo = &application_info,
  412. .enabledLayerCount = layers.size(),
  413. .ppEnabledLayerNames = layers.data(),
  414. .enabledExtensionCount = extensions.size(),
  415. .ppEnabledExtensionNames = extensions.data(),
  416. };
  417. VkInstance instance;
  418. Check(dispatch.vkCreateInstance(&ci, nullptr, &instance));
  419. if (!Proc(dispatch.vkDestroyInstance, dispatch, "vkDestroyInstance", instance)) {
  420. // We successfully created an instance but the destroy function couldn't be loaded.
  421. // This is a good moment to panic.
  422. throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
  423. }
  424. return Instance(instance, dispatch);
  425. }
  426. std::vector<VkPhysicalDevice> Instance::EnumeratePhysicalDevices() const {
  427. u32 num;
  428. Check(dld->vkEnumeratePhysicalDevices(handle, &num, nullptr));
  429. std::vector<VkPhysicalDevice> physical_devices(num);
  430. Check(dld->vkEnumeratePhysicalDevices(handle, &num, physical_devices.data()));
  431. SortPhysicalDevices(physical_devices, *dld);
  432. return physical_devices;
  433. }
  434. DebugUtilsMessenger Instance::CreateDebugUtilsMessenger(
  435. const VkDebugUtilsMessengerCreateInfoEXT& create_info) const {
  436. VkDebugUtilsMessengerEXT object;
  437. Check(dld->vkCreateDebugUtilsMessengerEXT(handle, &create_info, nullptr, &object));
  438. return DebugUtilsMessenger(object, handle, *dld);
  439. }
  440. void Buffer::BindMemory(VkDeviceMemory memory, VkDeviceSize offset) const {
  441. Check(dld->vkBindBufferMemory(owner, handle, memory, offset));
  442. }
  443. void Buffer::SetObjectNameEXT(const char* name) const {
  444. SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_BUFFER, name);
  445. }
  446. void BufferView::SetObjectNameEXT(const char* name) const {
  447. SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_BUFFER_VIEW, name);
  448. }
  449. void Image::BindMemory(VkDeviceMemory memory, VkDeviceSize offset) const {
  450. Check(dld->vkBindImageMemory(owner, handle, memory, offset));
  451. }
  452. void Image::SetObjectNameEXT(const char* name) const {
  453. SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_IMAGE, name);
  454. }
  455. void ImageView::SetObjectNameEXT(const char* name) const {
  456. SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_IMAGE_VIEW, name);
  457. }
  458. int DeviceMemory::GetMemoryFdKHR() const {
  459. const VkMemoryGetFdInfoKHR get_fd_info{
  460. .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
  461. .pNext = nullptr,
  462. .memory = handle,
  463. .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
  464. };
  465. int fd;
  466. Check(dld->vkGetMemoryFdKHR(owner, &get_fd_info, &fd));
  467. return fd;
  468. }
  469. #ifdef _WIN32
  470. HANDLE DeviceMemory::GetMemoryWin32HandleKHR() const {
  471. const VkMemoryGetWin32HandleInfoKHR get_win32_handle_info{
  472. .sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
  473. .pNext = nullptr,
  474. .memory = handle,
  475. .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR,
  476. };
  477. HANDLE win32_handle;
  478. Check(dld->vkGetMemoryWin32HandleKHR(owner, &get_win32_handle_info, &win32_handle));
  479. return win32_handle;
  480. }
  481. #endif
  482. void DeviceMemory::SetObjectNameEXT(const char* name) const {
  483. SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_DEVICE_MEMORY, name);
  484. }
  485. void Fence::SetObjectNameEXT(const char* name) const {
  486. SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_FENCE, name);
  487. }
  488. void Framebuffer::SetObjectNameEXT(const char* name) const {
  489. SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_FRAMEBUFFER, name);
  490. }
  491. DescriptorSets DescriptorPool::Allocate(const VkDescriptorSetAllocateInfo& ai) const {
  492. const std::size_t num = ai.descriptorSetCount;
  493. std::unique_ptr sets = std::make_unique<VkDescriptorSet[]>(num);
  494. switch (const VkResult result = dld->vkAllocateDescriptorSets(owner, &ai, sets.get())) {
  495. case VK_SUCCESS:
  496. return DescriptorSets(std::move(sets), num, owner, handle, *dld);
  497. case VK_ERROR_OUT_OF_POOL_MEMORY:
  498. return {};
  499. default:
  500. throw Exception(result);
  501. }
  502. }
  503. void DescriptorPool::SetObjectNameEXT(const char* name) const {
  504. SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_DESCRIPTOR_POOL, name);
  505. }
  506. CommandBuffers CommandPool::Allocate(std::size_t num_buffers, VkCommandBufferLevel level) const {
  507. const VkCommandBufferAllocateInfo ai{
  508. .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
  509. .pNext = nullptr,
  510. .commandPool = handle,
  511. .level = level,
  512. .commandBufferCount = static_cast<u32>(num_buffers),
  513. };
  514. std::unique_ptr buffers = std::make_unique<VkCommandBuffer[]>(num_buffers);
  515. switch (const VkResult result = dld->vkAllocateCommandBuffers(owner, &ai, buffers.get())) {
  516. case VK_SUCCESS:
  517. return CommandBuffers(std::move(buffers), num_buffers, owner, handle, *dld);
  518. case VK_ERROR_OUT_OF_POOL_MEMORY:
  519. return {};
  520. default:
  521. throw Exception(result);
  522. }
  523. }
  524. void CommandPool::SetObjectNameEXT(const char* name) const {
  525. SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_COMMAND_POOL, name);
  526. }
  527. std::vector<VkImage> SwapchainKHR::GetImages() const {
  528. u32 num;
  529. Check(dld->vkGetSwapchainImagesKHR(owner, handle, &num, nullptr));
  530. std::vector<VkImage> images(num);
  531. Check(dld->vkGetSwapchainImagesKHR(owner, handle, &num, images.data()));
  532. return images;
  533. }
  534. void Event::SetObjectNameEXT(const char* name) const {
  535. SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_EVENT, name);
  536. }
  537. void ShaderModule::SetObjectNameEXT(const char* name) const {
  538. SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_SHADER_MODULE, name);
  539. }
  540. void Semaphore::SetObjectNameEXT(const char* name) const {
  541. SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_SEMAPHORE, name);
  542. }
  543. Device Device::Create(VkPhysicalDevice physical_device, Span<VkDeviceQueueCreateInfo> queues_ci,
  544. Span<const char*> enabled_extensions, const void* next,
  545. DeviceDispatch& dispatch) {
  546. const VkDeviceCreateInfo ci{
  547. .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
  548. .pNext = next,
  549. .flags = 0,
  550. .queueCreateInfoCount = queues_ci.size(),
  551. .pQueueCreateInfos = queues_ci.data(),
  552. .enabledLayerCount = 0,
  553. .ppEnabledLayerNames = nullptr,
  554. .enabledExtensionCount = enabled_extensions.size(),
  555. .ppEnabledExtensionNames = enabled_extensions.data(),
  556. .pEnabledFeatures = nullptr,
  557. };
  558. VkDevice device;
  559. Check(dispatch.vkCreateDevice(physical_device, &ci, nullptr, &device));
  560. Load(device, dispatch);
  561. return Device(device, dispatch);
  562. }
  563. Queue Device::GetQueue(u32 family_index) const noexcept {
  564. VkQueue queue;
  565. dld->vkGetDeviceQueue(handle, family_index, 0, &queue);
  566. return Queue(queue, *dld);
  567. }
  568. Buffer Device::CreateBuffer(const VkBufferCreateInfo& ci) const {
  569. VkBuffer object;
  570. Check(dld->vkCreateBuffer(handle, &ci, nullptr, &object));
  571. return Buffer(object, handle, *dld);
  572. }
  573. BufferView Device::CreateBufferView(const VkBufferViewCreateInfo& ci) const {
  574. VkBufferView object;
  575. Check(dld->vkCreateBufferView(handle, &ci, nullptr, &object));
  576. return BufferView(object, handle, *dld);
  577. }
  578. Image Device::CreateImage(const VkImageCreateInfo& ci) const {
  579. VkImage object;
  580. Check(dld->vkCreateImage(handle, &ci, nullptr, &object));
  581. return Image(object, handle, *dld);
  582. }
  583. ImageView Device::CreateImageView(const VkImageViewCreateInfo& ci) const {
  584. VkImageView object;
  585. Check(dld->vkCreateImageView(handle, &ci, nullptr, &object));
  586. return ImageView(object, handle, *dld);
  587. }
  588. Semaphore Device::CreateSemaphore() const {
  589. static constexpr VkSemaphoreCreateInfo ci{
  590. .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
  591. .pNext = nullptr,
  592. .flags = 0,
  593. };
  594. return CreateSemaphore(ci);
  595. }
  596. Semaphore Device::CreateSemaphore(const VkSemaphoreCreateInfo& ci) const {
  597. VkSemaphore object;
  598. Check(dld->vkCreateSemaphore(handle, &ci, nullptr, &object));
  599. return Semaphore(object, handle, *dld);
  600. }
  601. Fence Device::CreateFence(const VkFenceCreateInfo& ci) const {
  602. VkFence object;
  603. Check(dld->vkCreateFence(handle, &ci, nullptr, &object));
  604. return Fence(object, handle, *dld);
  605. }
  606. DescriptorPool Device::CreateDescriptorPool(const VkDescriptorPoolCreateInfo& ci) const {
  607. VkDescriptorPool object;
  608. Check(dld->vkCreateDescriptorPool(handle, &ci, nullptr, &object));
  609. return DescriptorPool(object, handle, *dld);
  610. }
  611. RenderPass Device::CreateRenderPass(const VkRenderPassCreateInfo& ci) const {
  612. VkRenderPass object;
  613. Check(dld->vkCreateRenderPass(handle, &ci, nullptr, &object));
  614. return RenderPass(object, handle, *dld);
  615. }
  616. DescriptorSetLayout Device::CreateDescriptorSetLayout(
  617. const VkDescriptorSetLayoutCreateInfo& ci) const {
  618. VkDescriptorSetLayout object;
  619. Check(dld->vkCreateDescriptorSetLayout(handle, &ci, nullptr, &object));
  620. return DescriptorSetLayout(object, handle, *dld);
  621. }
  622. PipelineLayout Device::CreatePipelineLayout(const VkPipelineLayoutCreateInfo& ci) const {
  623. VkPipelineLayout object;
  624. Check(dld->vkCreatePipelineLayout(handle, &ci, nullptr, &object));
  625. return PipelineLayout(object, handle, *dld);
  626. }
  627. Pipeline Device::CreateGraphicsPipeline(const VkGraphicsPipelineCreateInfo& ci) const {
  628. VkPipeline object;
  629. Check(dld->vkCreateGraphicsPipelines(handle, nullptr, 1, &ci, nullptr, &object));
  630. return Pipeline(object, handle, *dld);
  631. }
  632. Pipeline Device::CreateComputePipeline(const VkComputePipelineCreateInfo& ci) const {
  633. VkPipeline object;
  634. Check(dld->vkCreateComputePipelines(handle, nullptr, 1, &ci, nullptr, &object));
  635. return Pipeline(object, handle, *dld);
  636. }
  637. Sampler Device::CreateSampler(const VkSamplerCreateInfo& ci) const {
  638. VkSampler object;
  639. Check(dld->vkCreateSampler(handle, &ci, nullptr, &object));
  640. return Sampler(object, handle, *dld);
  641. }
  642. Framebuffer Device::CreateFramebuffer(const VkFramebufferCreateInfo& ci) const {
  643. VkFramebuffer object;
  644. Check(dld->vkCreateFramebuffer(handle, &ci, nullptr, &object));
  645. return Framebuffer(object, handle, *dld);
  646. }
  647. CommandPool Device::CreateCommandPool(const VkCommandPoolCreateInfo& ci) const {
  648. VkCommandPool object;
  649. Check(dld->vkCreateCommandPool(handle, &ci, nullptr, &object));
  650. return CommandPool(object, handle, *dld);
  651. }
  652. DescriptorUpdateTemplateKHR Device::CreateDescriptorUpdateTemplateKHR(
  653. const VkDescriptorUpdateTemplateCreateInfoKHR& ci) const {
  654. VkDescriptorUpdateTemplateKHR object;
  655. Check(dld->vkCreateDescriptorUpdateTemplateKHR(handle, &ci, nullptr, &object));
  656. return DescriptorUpdateTemplateKHR(object, handle, *dld);
  657. }
  658. QueryPool Device::CreateQueryPool(const VkQueryPoolCreateInfo& ci) const {
  659. VkQueryPool object;
  660. Check(dld->vkCreateQueryPool(handle, &ci, nullptr, &object));
  661. return QueryPool(object, handle, *dld);
  662. }
  663. ShaderModule Device::CreateShaderModule(const VkShaderModuleCreateInfo& ci) const {
  664. VkShaderModule object;
  665. Check(dld->vkCreateShaderModule(handle, &ci, nullptr, &object));
  666. return ShaderModule(object, handle, *dld);
  667. }
  668. Event Device::CreateEvent() const {
  669. static constexpr VkEventCreateInfo ci{
  670. .sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
  671. .pNext = nullptr,
  672. .flags = 0,
  673. };
  674. VkEvent object;
  675. Check(dld->vkCreateEvent(handle, &ci, nullptr, &object));
  676. return Event(object, handle, *dld);
  677. }
  678. SwapchainKHR Device::CreateSwapchainKHR(const VkSwapchainCreateInfoKHR& ci) const {
  679. VkSwapchainKHR object;
  680. Check(dld->vkCreateSwapchainKHR(handle, &ci, nullptr, &object));
  681. return SwapchainKHR(object, handle, *dld);
  682. }
  683. DeviceMemory Device::TryAllocateMemory(const VkMemoryAllocateInfo& ai) const noexcept {
  684. VkDeviceMemory memory;
  685. if (dld->vkAllocateMemory(handle, &ai, nullptr, &memory) != VK_SUCCESS) {
  686. return {};
  687. }
  688. return DeviceMemory(memory, handle, *dld);
  689. }
  690. DeviceMemory Device::AllocateMemory(const VkMemoryAllocateInfo& ai) const {
  691. VkDeviceMemory memory;
  692. Check(dld->vkAllocateMemory(handle, &ai, nullptr, &memory));
  693. return DeviceMemory(memory, handle, *dld);
  694. }
  695. VkMemoryRequirements Device::GetBufferMemoryRequirements(VkBuffer buffer) const noexcept {
  696. VkMemoryRequirements requirements;
  697. dld->vkGetBufferMemoryRequirements(handle, buffer, &requirements);
  698. return requirements;
  699. }
  700. VkMemoryRequirements Device::GetImageMemoryRequirements(VkImage image) const noexcept {
  701. VkMemoryRequirements requirements;
  702. dld->vkGetImageMemoryRequirements(handle, image, &requirements);
  703. return requirements;
  704. }
  705. void Device::UpdateDescriptorSets(Span<VkWriteDescriptorSet> writes,
  706. Span<VkCopyDescriptorSet> copies) const noexcept {
  707. dld->vkUpdateDescriptorSets(handle, writes.size(), writes.data(), copies.size(), copies.data());
  708. }
  709. VkPhysicalDeviceProperties PhysicalDevice::GetProperties() const noexcept {
  710. VkPhysicalDeviceProperties properties;
  711. dld->vkGetPhysicalDeviceProperties(physical_device, &properties);
  712. return properties;
  713. }
  714. void PhysicalDevice::GetProperties2KHR(VkPhysicalDeviceProperties2KHR& properties) const noexcept {
  715. dld->vkGetPhysicalDeviceProperties2KHR(physical_device, &properties);
  716. }
  717. VkPhysicalDeviceFeatures PhysicalDevice::GetFeatures() const noexcept {
  718. VkPhysicalDeviceFeatures2KHR features2;
  719. features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
  720. features2.pNext = nullptr;
  721. dld->vkGetPhysicalDeviceFeatures2KHR(physical_device, &features2);
  722. return features2.features;
  723. }
  724. void PhysicalDevice::GetFeatures2KHR(VkPhysicalDeviceFeatures2KHR& features) const noexcept {
  725. dld->vkGetPhysicalDeviceFeatures2KHR(physical_device, &features);
  726. }
  727. VkFormatProperties PhysicalDevice::GetFormatProperties(VkFormat format) const noexcept {
  728. VkFormatProperties properties;
  729. dld->vkGetPhysicalDeviceFormatProperties(physical_device, format, &properties);
  730. return properties;
  731. }
  732. std::vector<VkExtensionProperties> PhysicalDevice::EnumerateDeviceExtensionProperties() const {
  733. u32 num;
  734. dld->vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &num, nullptr);
  735. std::vector<VkExtensionProperties> properties(num);
  736. dld->vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &num, properties.data());
  737. return properties;
  738. }
  739. std::vector<VkQueueFamilyProperties> PhysicalDevice::GetQueueFamilyProperties() const {
  740. u32 num;
  741. dld->vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &num, nullptr);
  742. std::vector<VkQueueFamilyProperties> properties(num);
  743. dld->vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &num, properties.data());
  744. return properties;
  745. }
  746. bool PhysicalDevice::GetSurfaceSupportKHR(u32 queue_family_index, VkSurfaceKHR surface) const {
  747. VkBool32 supported;
  748. Check(dld->vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, queue_family_index, surface,
  749. &supported));
  750. return supported == VK_TRUE;
  751. }
  752. VkSurfaceCapabilitiesKHR PhysicalDevice::GetSurfaceCapabilitiesKHR(VkSurfaceKHR surface) const {
  753. VkSurfaceCapabilitiesKHR capabilities;
  754. Check(dld->vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, surface, &capabilities));
  755. return capabilities;
  756. }
  757. std::vector<VkSurfaceFormatKHR> PhysicalDevice::GetSurfaceFormatsKHR(VkSurfaceKHR surface) const {
  758. u32 num;
  759. Check(dld->vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &num, nullptr));
  760. std::vector<VkSurfaceFormatKHR> formats(num);
  761. Check(
  762. dld->vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &num, formats.data()));
  763. return formats;
  764. }
  765. std::vector<VkPresentModeKHR> PhysicalDevice::GetSurfacePresentModesKHR(
  766. VkSurfaceKHR surface) const {
  767. u32 num;
  768. Check(dld->vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &num, nullptr));
  769. std::vector<VkPresentModeKHR> modes(num);
  770. Check(dld->vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &num,
  771. modes.data()));
  772. return modes;
  773. }
  774. VkPhysicalDeviceMemoryProperties PhysicalDevice::GetMemoryProperties() const noexcept {
  775. VkPhysicalDeviceMemoryProperties properties;
  776. dld->vkGetPhysicalDeviceMemoryProperties(physical_device, &properties);
  777. return properties;
  778. }
  779. u32 AvailableVersion(const InstanceDispatch& dld) noexcept {
  780. PFN_vkEnumerateInstanceVersion vkEnumerateInstanceVersion;
  781. if (!Proc(vkEnumerateInstanceVersion, dld, "vkEnumerateInstanceVersion")) {
  782. // If the procedure is not found, Vulkan 1.0 is assumed
  783. return VK_API_VERSION_1_0;
  784. }
  785. u32 version;
  786. if (const VkResult result = vkEnumerateInstanceVersion(&version); result != VK_SUCCESS) {
  787. LOG_ERROR(Render_Vulkan, "vkEnumerateInstanceVersion returned {}, assuming Vulkan 1.1",
  788. ToString(result));
  789. return VK_API_VERSION_1_1;
  790. }
  791. return version;
  792. }
  793. std::optional<std::vector<VkExtensionProperties>> EnumerateInstanceExtensionProperties(
  794. const InstanceDispatch& dld) {
  795. u32 num;
  796. if (dld.vkEnumerateInstanceExtensionProperties(nullptr, &num, nullptr) != VK_SUCCESS) {
  797. return std::nullopt;
  798. }
  799. std::vector<VkExtensionProperties> properties(num);
  800. if (dld.vkEnumerateInstanceExtensionProperties(nullptr, &num, properties.data()) !=
  801. VK_SUCCESS) {
  802. return std::nullopt;
  803. }
  804. return properties;
  805. }
  806. std::optional<std::vector<VkLayerProperties>> EnumerateInstanceLayerProperties(
  807. const InstanceDispatch& dld) {
  808. u32 num;
  809. if (dld.vkEnumerateInstanceLayerProperties(&num, nullptr) != VK_SUCCESS) {
  810. return std::nullopt;
  811. }
  812. std::vector<VkLayerProperties> properties(num);
  813. if (dld.vkEnumerateInstanceLayerProperties(&num, properties.data()) != VK_SUCCESS) {
  814. return std::nullopt;
  815. }
  816. return properties;
  817. }
  818. } // namespace Vulkan::vk