1 // Copyright 2017 The Dawn Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "dawn_native/vulkan/VulkanFunctions.h" 16 17 #include "common/DynamicLib.h" 18 #include "dawn_native/vulkan/VulkanInfo.h" 19 20 namespace dawn_native { namespace vulkan { 21 22 #define GET_GLOBAL_PROC(name) \ 23 do { \ 24 name = reinterpret_cast<decltype(name)>(GetInstanceProcAddr(nullptr, "vk" #name)); \ 25 if (name == nullptr) { \ 26 return DAWN_INTERNAL_ERROR(std::string("Couldn't get proc vk") + #name); \ 27 } \ 28 } while (0) 29 LoadGlobalProcs(const DynamicLib & vulkanLib)30 MaybeError VulkanFunctions::LoadGlobalProcs(const DynamicLib& vulkanLib) { 31 if (!vulkanLib.GetProc(&GetInstanceProcAddr, "vkGetInstanceProcAddr")) { 32 return DAWN_INTERNAL_ERROR("Couldn't get vkGetInstanceProcAddr"); 33 } 34 35 GET_GLOBAL_PROC(CreateInstance); 36 GET_GLOBAL_PROC(EnumerateInstanceExtensionProperties); 37 GET_GLOBAL_PROC(EnumerateInstanceLayerProperties); 38 39 // Is not available in Vulkan 1.0, so allow nullptr 40 EnumerateInstanceVersion = reinterpret_cast<decltype(EnumerateInstanceVersion)>( 41 GetInstanceProcAddr(nullptr, "vkEnumerateInstanceVersion")); 42 43 return {}; 44 } 45 46 #define GET_INSTANCE_PROC_BASE(name, procName) \ 47 do { \ 48 name = reinterpret_cast<decltype(name)>(GetInstanceProcAddr(instance, "vk" #procName)); \ 49 if (name == nullptr) { \ 50 return DAWN_INTERNAL_ERROR(std::string("Couldn't get proc vk") + #procName); \ 51 } \ 52 } while (0) 53 54 #define GET_INSTANCE_PROC(name) GET_INSTANCE_PROC_BASE(name, name) 55 #define GET_INSTANCE_PROC_VENDOR(name, vendor) GET_INSTANCE_PROC_BASE(name, name##vendor) 56 LoadInstanceProcs(VkInstance instance,const VulkanGlobalInfo & globalInfo)57 MaybeError VulkanFunctions::LoadInstanceProcs(VkInstance instance, 58 const VulkanGlobalInfo& globalInfo) { 59 // Load this proc first so that we can destroy the instance even if some other 60 // GET_INSTANCE_PROC fails 61 GET_INSTANCE_PROC(DestroyInstance); 62 63 GET_INSTANCE_PROC(CreateDevice); 64 GET_INSTANCE_PROC(DestroyDevice); 65 GET_INSTANCE_PROC(EnumerateDeviceExtensionProperties); 66 GET_INSTANCE_PROC(EnumerateDeviceLayerProperties); 67 GET_INSTANCE_PROC(EnumeratePhysicalDevices); 68 GET_INSTANCE_PROC(GetDeviceProcAddr); 69 GET_INSTANCE_PROC(GetPhysicalDeviceFeatures); 70 GET_INSTANCE_PROC(GetPhysicalDeviceFormatProperties); 71 GET_INSTANCE_PROC(GetPhysicalDeviceImageFormatProperties); 72 GET_INSTANCE_PROC(GetPhysicalDeviceMemoryProperties); 73 GET_INSTANCE_PROC(GetPhysicalDeviceProperties); 74 GET_INSTANCE_PROC(GetPhysicalDeviceQueueFamilyProperties); 75 GET_INSTANCE_PROC(GetPhysicalDeviceSparseImageFormatProperties); 76 77 if (globalInfo.HasExt(InstanceExt::DebugUtils)) { 78 GET_INSTANCE_PROC(CmdBeginDebugUtilsLabelEXT); 79 GET_INSTANCE_PROC(CmdEndDebugUtilsLabelEXT); 80 GET_INSTANCE_PROC(CmdInsertDebugUtilsLabelEXT); 81 GET_INSTANCE_PROC(CreateDebugUtilsMessengerEXT); 82 GET_INSTANCE_PROC(DestroyDebugUtilsMessengerEXT); 83 GET_INSTANCE_PROC(QueueBeginDebugUtilsLabelEXT); 84 GET_INSTANCE_PROC(QueueEndDebugUtilsLabelEXT); 85 GET_INSTANCE_PROC(QueueInsertDebugUtilsLabelEXT); 86 GET_INSTANCE_PROC(SetDebugUtilsObjectNameEXT); 87 GET_INSTANCE_PROC(SetDebugUtilsObjectTagEXT); 88 GET_INSTANCE_PROC(SubmitDebugUtilsMessageEXT); 89 } 90 91 // Vulkan 1.1 is not required to report promoted extensions from 1.0 and is not required to 92 // support the vendor entrypoint in GetProcAddress. 93 if (globalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) { 94 GET_INSTANCE_PROC(GetPhysicalDeviceExternalBufferProperties); 95 } else if (globalInfo.HasExt(InstanceExt::ExternalMemoryCapabilities)) { 96 GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceExternalBufferProperties, KHR); 97 } 98 99 if (globalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) { 100 GET_INSTANCE_PROC(GetPhysicalDeviceExternalSemaphoreProperties); 101 } else if (globalInfo.HasExt(InstanceExt::ExternalSemaphoreCapabilities)) { 102 GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceExternalSemaphoreProperties, KHR); 103 } 104 105 if (globalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) { 106 GET_INSTANCE_PROC(GetPhysicalDeviceFeatures2); 107 GET_INSTANCE_PROC(GetPhysicalDeviceProperties2); 108 GET_INSTANCE_PROC(GetPhysicalDeviceFormatProperties2); 109 GET_INSTANCE_PROC(GetPhysicalDeviceImageFormatProperties2); 110 GET_INSTANCE_PROC(GetPhysicalDeviceQueueFamilyProperties2); 111 GET_INSTANCE_PROC(GetPhysicalDeviceMemoryProperties2); 112 GET_INSTANCE_PROC(GetPhysicalDeviceSparseImageFormatProperties2); 113 } else if (globalInfo.HasExt(InstanceExt::GetPhysicalDeviceProperties2)) { 114 GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceFeatures2, KHR); 115 GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceProperties2, KHR); 116 GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceFormatProperties2, KHR); 117 GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceImageFormatProperties2, KHR); 118 GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceQueueFamilyProperties2, KHR); 119 GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceMemoryProperties2, KHR); 120 GET_INSTANCE_PROC_VENDOR(GetPhysicalDeviceSparseImageFormatProperties2, KHR); 121 } 122 123 if (globalInfo.HasExt(InstanceExt::Surface)) { 124 GET_INSTANCE_PROC(DestroySurfaceKHR); 125 GET_INSTANCE_PROC(GetPhysicalDeviceSurfaceSupportKHR); 126 GET_INSTANCE_PROC(GetPhysicalDeviceSurfaceCapabilitiesKHR); 127 GET_INSTANCE_PROC(GetPhysicalDeviceSurfaceFormatsKHR); 128 GET_INSTANCE_PROC(GetPhysicalDeviceSurfacePresentModesKHR); 129 } 130 131 #if defined(VK_USE_PLATFORM_FUCHSIA) 132 if (globalInfo.HasExt(InstanceExt::FuchsiaImagePipeSurface)) { 133 GET_INSTANCE_PROC(CreateImagePipeSurfaceFUCHSIA); 134 } 135 #endif // defined(VK_USE_PLATFORM_FUCHSIA) 136 137 #if defined(DAWN_ENABLE_BACKEND_METAL) 138 if (globalInfo.HasExt(InstanceExt::MetalSurface)) { 139 GET_INSTANCE_PROC(CreateMetalSurfaceEXT); 140 } 141 #endif // defined(DAWN_ENABLE_BACKEND_METAL) 142 143 #if defined(DAWN_PLATFORM_WINDOWS) 144 if (globalInfo.HasExt(InstanceExt::Win32Surface)) { 145 GET_INSTANCE_PROC(CreateWin32SurfaceKHR); 146 GET_INSTANCE_PROC(GetPhysicalDeviceWin32PresentationSupportKHR); 147 } 148 #endif // defined(DAWN_PLATFORM_WINDOWS) 149 150 #if defined(DAWN_USE_X11) 151 if (globalInfo.HasExt(InstanceExt::XlibSurface)) { 152 GET_INSTANCE_PROC(CreateXlibSurfaceKHR); 153 GET_INSTANCE_PROC(GetPhysicalDeviceXlibPresentationSupportKHR); 154 } 155 if (globalInfo.HasExt(InstanceExt::XcbSurface)) { 156 GET_INSTANCE_PROC(CreateXcbSurfaceKHR); 157 GET_INSTANCE_PROC(GetPhysicalDeviceXcbPresentationSupportKHR); 158 } 159 #endif // defined(DAWN_USE_X11) 160 return {}; 161 } 162 163 #define GET_DEVICE_PROC(name) \ 164 do { \ 165 name = reinterpret_cast<decltype(name)>(GetDeviceProcAddr(device, "vk" #name)); \ 166 if (name == nullptr) { \ 167 return DAWN_INTERNAL_ERROR(std::string("Couldn't get proc vk") + #name); \ 168 } \ 169 } while (0) 170 LoadDeviceProcs(VkDevice device,const VulkanDeviceInfo & deviceInfo)171 MaybeError VulkanFunctions::LoadDeviceProcs(VkDevice device, 172 const VulkanDeviceInfo& deviceInfo) { 173 GET_DEVICE_PROC(AllocateCommandBuffers); 174 GET_DEVICE_PROC(AllocateDescriptorSets); 175 GET_DEVICE_PROC(AllocateMemory); 176 GET_DEVICE_PROC(BeginCommandBuffer); 177 GET_DEVICE_PROC(BindBufferMemory); 178 GET_DEVICE_PROC(BindImageMemory); 179 GET_DEVICE_PROC(CmdBeginQuery); 180 GET_DEVICE_PROC(CmdBeginRenderPass); 181 GET_DEVICE_PROC(CmdBindDescriptorSets); 182 GET_DEVICE_PROC(CmdBindIndexBuffer); 183 GET_DEVICE_PROC(CmdBindPipeline); 184 GET_DEVICE_PROC(CmdBindVertexBuffers); 185 GET_DEVICE_PROC(CmdBlitImage); 186 GET_DEVICE_PROC(CmdClearAttachments); 187 GET_DEVICE_PROC(CmdClearColorImage); 188 GET_DEVICE_PROC(CmdClearDepthStencilImage); 189 GET_DEVICE_PROC(CmdCopyBuffer); 190 GET_DEVICE_PROC(CmdCopyBufferToImage); 191 GET_DEVICE_PROC(CmdCopyImage); 192 GET_DEVICE_PROC(CmdCopyImageToBuffer); 193 GET_DEVICE_PROC(CmdCopyQueryPoolResults); 194 GET_DEVICE_PROC(CmdDispatch); 195 GET_DEVICE_PROC(CmdDispatchIndirect); 196 GET_DEVICE_PROC(CmdDraw); 197 GET_DEVICE_PROC(CmdDrawIndexed); 198 GET_DEVICE_PROC(CmdDrawIndexedIndirect); 199 GET_DEVICE_PROC(CmdDrawIndirect); 200 GET_DEVICE_PROC(CmdEndQuery); 201 GET_DEVICE_PROC(CmdEndRenderPass); 202 GET_DEVICE_PROC(CmdExecuteCommands); 203 GET_DEVICE_PROC(CmdFillBuffer); 204 GET_DEVICE_PROC(CmdNextSubpass); 205 GET_DEVICE_PROC(CmdPipelineBarrier); 206 GET_DEVICE_PROC(CmdPushConstants); 207 GET_DEVICE_PROC(CmdResetEvent); 208 GET_DEVICE_PROC(CmdResetQueryPool); 209 GET_DEVICE_PROC(CmdResolveImage); 210 GET_DEVICE_PROC(CmdSetBlendConstants); 211 GET_DEVICE_PROC(CmdSetDepthBias); 212 GET_DEVICE_PROC(CmdSetDepthBounds); 213 GET_DEVICE_PROC(CmdSetEvent); 214 GET_DEVICE_PROC(CmdSetLineWidth); 215 GET_DEVICE_PROC(CmdSetScissor); 216 GET_DEVICE_PROC(CmdSetStencilCompareMask); 217 GET_DEVICE_PROC(CmdSetStencilReference); 218 GET_DEVICE_PROC(CmdSetStencilWriteMask); 219 GET_DEVICE_PROC(CmdSetViewport); 220 GET_DEVICE_PROC(CmdUpdateBuffer); 221 GET_DEVICE_PROC(CmdWaitEvents); 222 GET_DEVICE_PROC(CmdWriteTimestamp); 223 GET_DEVICE_PROC(CreateBuffer); 224 GET_DEVICE_PROC(CreateBufferView); 225 GET_DEVICE_PROC(CreateCommandPool); 226 GET_DEVICE_PROC(CreateComputePipelines); 227 GET_DEVICE_PROC(CreateDescriptorPool); 228 GET_DEVICE_PROC(CreateDescriptorSetLayout); 229 GET_DEVICE_PROC(CreateEvent); 230 GET_DEVICE_PROC(CreateFence); 231 GET_DEVICE_PROC(CreateFramebuffer); 232 GET_DEVICE_PROC(CreateGraphicsPipelines); 233 GET_DEVICE_PROC(CreateImage); 234 GET_DEVICE_PROC(CreateImageView); 235 GET_DEVICE_PROC(CreatePipelineCache); 236 GET_DEVICE_PROC(CreatePipelineLayout); 237 GET_DEVICE_PROC(CreateQueryPool); 238 GET_DEVICE_PROC(CreateRenderPass); 239 GET_DEVICE_PROC(CreateSampler); 240 GET_DEVICE_PROC(CreateSemaphore); 241 GET_DEVICE_PROC(CreateShaderModule); 242 GET_DEVICE_PROC(DestroyBuffer); 243 GET_DEVICE_PROC(DestroyBufferView); 244 GET_DEVICE_PROC(DestroyCommandPool); 245 GET_DEVICE_PROC(DestroyDescriptorPool); 246 GET_DEVICE_PROC(DestroyDescriptorSetLayout); 247 GET_DEVICE_PROC(DestroyEvent); 248 GET_DEVICE_PROC(DestroyFence); 249 GET_DEVICE_PROC(DestroyFramebuffer); 250 GET_DEVICE_PROC(DestroyImage); 251 GET_DEVICE_PROC(DestroyImageView); 252 GET_DEVICE_PROC(DestroyPipeline); 253 GET_DEVICE_PROC(DestroyPipelineCache); 254 GET_DEVICE_PROC(DestroyPipelineLayout); 255 GET_DEVICE_PROC(DestroyQueryPool); 256 GET_DEVICE_PROC(DestroyRenderPass); 257 GET_DEVICE_PROC(DestroySampler); 258 GET_DEVICE_PROC(DestroySemaphore); 259 GET_DEVICE_PROC(DestroyShaderModule); 260 GET_DEVICE_PROC(DeviceWaitIdle); 261 GET_DEVICE_PROC(EndCommandBuffer); 262 GET_DEVICE_PROC(FlushMappedMemoryRanges); 263 GET_DEVICE_PROC(FreeCommandBuffers); 264 GET_DEVICE_PROC(FreeDescriptorSets); 265 GET_DEVICE_PROC(FreeMemory); 266 GET_DEVICE_PROC(GetBufferMemoryRequirements); 267 GET_DEVICE_PROC(GetDeviceMemoryCommitment); 268 GET_DEVICE_PROC(GetDeviceQueue); 269 GET_DEVICE_PROC(GetEventStatus); 270 GET_DEVICE_PROC(GetFenceStatus); 271 GET_DEVICE_PROC(GetImageMemoryRequirements); 272 GET_DEVICE_PROC(GetImageSparseMemoryRequirements); 273 GET_DEVICE_PROC(GetImageSubresourceLayout); 274 GET_DEVICE_PROC(GetPipelineCacheData); 275 GET_DEVICE_PROC(GetQueryPoolResults); 276 GET_DEVICE_PROC(GetRenderAreaGranularity); 277 GET_DEVICE_PROC(InvalidateMappedMemoryRanges); 278 GET_DEVICE_PROC(MapMemory); 279 GET_DEVICE_PROC(MergePipelineCaches); 280 GET_DEVICE_PROC(QueueBindSparse); 281 GET_DEVICE_PROC(QueueSubmit); 282 GET_DEVICE_PROC(QueueWaitIdle); 283 GET_DEVICE_PROC(ResetCommandBuffer); 284 GET_DEVICE_PROC(ResetCommandPool); 285 GET_DEVICE_PROC(ResetDescriptorPool); 286 GET_DEVICE_PROC(ResetEvent); 287 GET_DEVICE_PROC(ResetFences); 288 GET_DEVICE_PROC(SetEvent); 289 GET_DEVICE_PROC(UnmapMemory); 290 GET_DEVICE_PROC(UpdateDescriptorSets); 291 GET_DEVICE_PROC(WaitForFences); 292 293 if (deviceInfo.HasExt(DeviceExt::ExternalMemoryFD)) { 294 GET_DEVICE_PROC(GetMemoryFdKHR); 295 GET_DEVICE_PROC(GetMemoryFdPropertiesKHR); 296 } 297 298 if (deviceInfo.HasExt(DeviceExt::ExternalSemaphoreFD)) { 299 GET_DEVICE_PROC(ImportSemaphoreFdKHR); 300 GET_DEVICE_PROC(GetSemaphoreFdKHR); 301 } 302 303 if (deviceInfo.HasExt(DeviceExt::Swapchain)) { 304 GET_DEVICE_PROC(CreateSwapchainKHR); 305 GET_DEVICE_PROC(DestroySwapchainKHR); 306 GET_DEVICE_PROC(GetSwapchainImagesKHR); 307 GET_DEVICE_PROC(AcquireNextImageKHR); 308 GET_DEVICE_PROC(QueuePresentKHR); 309 } 310 311 if (deviceInfo.HasExt(DeviceExt::GetMemoryRequirements2)) { 312 GET_DEVICE_PROC(GetBufferMemoryRequirements2); 313 GET_DEVICE_PROC(GetImageMemoryRequirements2); 314 GET_DEVICE_PROC(GetImageSparseMemoryRequirements2); 315 } 316 317 #if VK_USE_PLATFORM_FUCHSIA 318 if (deviceInfo.HasExt(DeviceExt::ExternalMemoryZirconHandle)) { 319 GET_DEVICE_PROC(GetMemoryZirconHandleFUCHSIA); 320 GET_DEVICE_PROC(GetMemoryZirconHandlePropertiesFUCHSIA); 321 } 322 323 if (deviceInfo.HasExt(DeviceExt::ExternalSemaphoreZirconHandle)) { 324 GET_DEVICE_PROC(ImportSemaphoreZirconHandleFUCHSIA); 325 GET_DEVICE_PROC(GetSemaphoreZirconHandleFUCHSIA); 326 } 327 #endif 328 329 return {}; 330 } 331 332 }} // namespace dawn_native::vulkan 333