blob: 5c5073a309b6c362a3c35f35a69d200e02a02eca [file] [log] [blame]
Corentin Wallez4a9ef4e2018-07-18 11:40:26 +02001// Copyright 2017 The Dawn Authors
Corentin Wallezf2adf6d2017-11-17 17:52:04 -05002//
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
Corentin Wallezd37523f2018-07-24 13:53:51 +020015#include "dawn_native/vulkan/VulkanFunctions.h"
Corentin Wallezf2adf6d2017-11-17 17:52:04 -050016
Zhenyao Modf9d1b52019-11-13 19:33:59 +000017#include <pthread.h>
18
Corentin Wallezf2adf6d2017-11-17 17:52:04 -050019#include "common/DynamicLib.h"
Corentin Wallezd37523f2018-07-24 13:53:51 +020020#include "dawn_native/vulkan/VulkanInfo.h"
Corentin Wallezf2adf6d2017-11-17 17:52:04 -050021
Zhenyao Modf9d1b52019-11-13 19:33:59 +000022namespace {
23
24pthread_mutex_t g_vk_queue_submit_lock;
25
26PFN_vkQueueSubmit g_native_vk_queue_submit_fn = nullptr;
27
28VkResult vkQueueSubmit_ThreadSafe(
29 VkQueue queue,
30 uint32_t submitCount,
31 const VkSubmitInfo* pSubmits,
32 VkFence fence) {
33 pthread_mutex_lock(&g_vk_queue_submit_lock);
34 VkResult r = g_native_vk_queue_submit_fn(queue, submitCount, pSubmits, fence);
35 pthread_mutex_unlock(&g_vk_queue_submit_lock);
36 return r;
37}
38
39}
40
Corentin Wallez49a65d02018-07-24 16:45:45 +020041namespace dawn_native { namespace vulkan {
Corentin Wallezf2adf6d2017-11-17 17:52:04 -050042
Corentin Wallez23b27a22017-11-24 14:18:09 -050043#define GET_GLOBAL_PROC(name) \
44 name = reinterpret_cast<decltype(name)>(GetInstanceProcAddr(nullptr, "vk" #name)); \
45 if (name == nullptr) { \
Austin Eng5603dc92019-08-27 18:10:03 +000046 return DAWN_DEVICE_LOST_ERROR(std::string("Couldn't get proc vk") + #name); \
Corentin Wallez23b27a22017-11-24 14:18:09 -050047 }
Corentin Wallezf2adf6d2017-11-17 17:52:04 -050048
Corentin Wallez85df07a2018-12-03 12:49:56 +000049 MaybeError VulkanFunctions::LoadGlobalProcs(const DynamicLib& vulkanLib) {
Corentin Wallezf2adf6d2017-11-17 17:52:04 -050050 if (!vulkanLib.GetProc(&GetInstanceProcAddr, "vkGetInstanceProcAddr")) {
Austin Eng5603dc92019-08-27 18:10:03 +000051 return DAWN_DEVICE_LOST_ERROR("Couldn't get vkGetInstanceProcAddr");
Corentin Wallezf2adf6d2017-11-17 17:52:04 -050052 }
53
54 GET_GLOBAL_PROC(CreateInstance);
Corentin Wallezf2adf6d2017-11-17 17:52:04 -050055 GET_GLOBAL_PROC(EnumerateInstanceExtensionProperties);
56 GET_GLOBAL_PROC(EnumerateInstanceLayerProperties);
57
Idan Raiter7dec2d12019-07-29 23:31:49 +000058 // Is not available in Vulkan 1.0, so allow nullptr
59 EnumerateInstanceVersion = reinterpret_cast<decltype(EnumerateInstanceVersion)>(
60 GetInstanceProcAddr(nullptr, "vkEnumerateInstanceVersion"));
61
Corentin Wallez85df07a2018-12-03 12:49:56 +000062 return {};
Corentin Wallezf2adf6d2017-11-17 17:52:04 -050063 }
64
Corentin Wallez23b27a22017-11-24 14:18:09 -050065#define GET_INSTANCE_PROC(name) \
66 name = reinterpret_cast<decltype(name)>(GetInstanceProcAddr(instance, "vk" #name)); \
67 if (name == nullptr) { \
Austin Eng5603dc92019-08-27 18:10:03 +000068 return DAWN_DEVICE_LOST_ERROR(std::string("Couldn't get proc vk") + #name); \
Corentin Wallez23b27a22017-11-24 14:18:09 -050069 }
Corentin Wallez6d9a3b82017-11-20 10:51:23 -050070
Corentin Wallez85df07a2018-12-03 12:49:56 +000071 MaybeError VulkanFunctions::LoadInstanceProcs(VkInstance instance,
Idan Raiteref4f3bd2019-08-02 18:10:38 +000072 const VulkanGlobalInfo& globalInfo) {
Corentin Wallez23b27a22017-11-24 14:18:09 -050073 // Load this proc first so that we can destroy the instance even if some other
74 // GET_INSTANCE_PROC fails
Corentin Wallez02162332017-11-21 12:52:03 -050075 GET_INSTANCE_PROC(DestroyInstance);
76
Corentin Wallez6d9a3b82017-11-20 10:51:23 -050077 GET_INSTANCE_PROC(CreateDevice);
78 GET_INSTANCE_PROC(DestroyDevice);
79 GET_INSTANCE_PROC(EnumerateDeviceExtensionProperties);
80 GET_INSTANCE_PROC(EnumerateDeviceLayerProperties);
81 GET_INSTANCE_PROC(EnumeratePhysicalDevices);
Corentin Wallez02162332017-11-21 12:52:03 -050082 GET_INSTANCE_PROC(GetDeviceProcAddr);
Corentin Wallez6d9a3b82017-11-20 10:51:23 -050083 GET_INSTANCE_PROC(GetPhysicalDeviceFeatures);
84 GET_INSTANCE_PROC(GetPhysicalDeviceFormatProperties);
85 GET_INSTANCE_PROC(GetPhysicalDeviceImageFormatProperties);
86 GET_INSTANCE_PROC(GetPhysicalDeviceMemoryProperties);
87 GET_INSTANCE_PROC(GetPhysicalDeviceProperties);
88 GET_INSTANCE_PROC(GetPhysicalDeviceQueueFamilyProperties);
89 GET_INSTANCE_PROC(GetPhysicalDeviceSparseImageFormatProperties);
90
Idan Raiteref4f3bd2019-08-02 18:10:38 +000091 if (globalInfo.debugReport) {
Corentin Wallez6d9a3b82017-11-20 10:51:23 -050092 GET_INSTANCE_PROC(CreateDebugReportCallbackEXT);
93 GET_INSTANCE_PROC(DebugReportMessageEXT);
94 GET_INSTANCE_PROC(DestroyDebugReportCallbackEXT);
95 }
96
Idan Raiteref4f3bd2019-08-02 18:10:38 +000097 // Vulkan 1.1 is not required to report promoted extensions from 1.0
98 if (globalInfo.externalMemoryCapabilities ||
99 globalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
100 GET_INSTANCE_PROC(GetPhysicalDeviceExternalBufferPropertiesKHR);
101 }
102
103 if (globalInfo.externalSemaphoreCapabilities ||
104 globalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
105 GET_INSTANCE_PROC(GetPhysicalDeviceExternalSemaphorePropertiesKHR);
106 }
107
108 if (globalInfo.getPhysicalDeviceProperties2 ||
109 globalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
110 GET_INSTANCE_PROC(GetPhysicalDeviceFeatures2KHR);
111 GET_INSTANCE_PROC(GetPhysicalDeviceProperties2KHR);
112 GET_INSTANCE_PROC(GetPhysicalDeviceFormatProperties2KHR);
113 GET_INSTANCE_PROC(GetPhysicalDeviceImageFormatProperties2KHR);
114 GET_INSTANCE_PROC(GetPhysicalDeviceQueueFamilyProperties2KHR);
115 GET_INSTANCE_PROC(GetPhysicalDeviceMemoryProperties2KHR);
116 GET_INSTANCE_PROC(GetPhysicalDeviceSparseImageFormatProperties2KHR);
117 }
118
119 if (globalInfo.surface) {
Corentin Wallez02162332017-11-21 12:52:03 -0500120 GET_INSTANCE_PROC(DestroySurfaceKHR);
121 GET_INSTANCE_PROC(GetPhysicalDeviceSurfaceSupportKHR);
122 GET_INSTANCE_PROC(GetPhysicalDeviceSurfaceCapabilitiesKHR);
123 GET_INSTANCE_PROC(GetPhysicalDeviceSurfaceFormatsKHR);
124 GET_INSTANCE_PROC(GetPhysicalDeviceSurfacePresentModesKHR);
125 }
126
David 'Digit' Turnerb749d072019-09-09 10:52:08 +0000127#ifdef VK_USE_PLATFORM_FUCHSIA
128 if (globalInfo.fuchsiaImagePipeSurface) {
129 GET_INSTANCE_PROC(CreateImagePipeSurfaceFUCHSIA);
130 }
131#endif
132
Corentin Wallez85df07a2018-12-03 12:49:56 +0000133 return {};
Corentin Wallez02162332017-11-21 12:52:03 -0500134 }
135
Austin Eng5603dc92019-08-27 18:10:03 +0000136#define GET_DEVICE_PROC(name) \
137 name = reinterpret_cast<decltype(name)>(GetDeviceProcAddr(device, "vk" #name)); \
138 if (name == nullptr) { \
139 return DAWN_DEVICE_LOST_ERROR(std::string("Couldn't get proc vk") + #name); \
Corentin Wallez23b27a22017-11-24 14:18:09 -0500140 }
Corentin Wallez02162332017-11-21 12:52:03 -0500141
Corentin Wallez85df07a2018-12-03 12:49:56 +0000142 MaybeError VulkanFunctions::LoadDeviceProcs(VkDevice device,
143 const VulkanDeviceKnobs& usedKnobs) {
Corentin Wallez02162332017-11-21 12:52:03 -0500144 GET_DEVICE_PROC(AllocateCommandBuffers);
145 GET_DEVICE_PROC(AllocateDescriptorSets);
146 GET_DEVICE_PROC(AllocateMemory);
147 GET_DEVICE_PROC(BeginCommandBuffer);
148 GET_DEVICE_PROC(BindBufferMemory);
149 GET_DEVICE_PROC(BindImageMemory);
150 GET_DEVICE_PROC(CmdBeginQuery);
151 GET_DEVICE_PROC(CmdBeginRenderPass);
152 GET_DEVICE_PROC(CmdBindDescriptorSets);
153 GET_DEVICE_PROC(CmdBindIndexBuffer);
154 GET_DEVICE_PROC(CmdBindPipeline);
155 GET_DEVICE_PROC(CmdBindVertexBuffers);
156 GET_DEVICE_PROC(CmdBlitImage);
157 GET_DEVICE_PROC(CmdClearAttachments);
158 GET_DEVICE_PROC(CmdClearColorImage);
159 GET_DEVICE_PROC(CmdClearDepthStencilImage);
160 GET_DEVICE_PROC(CmdCopyBuffer);
161 GET_DEVICE_PROC(CmdCopyBufferToImage);
162 GET_DEVICE_PROC(CmdCopyImage);
163 GET_DEVICE_PROC(CmdCopyImageToBuffer);
164 GET_DEVICE_PROC(CmdCopyQueryPoolResults);
165 GET_DEVICE_PROC(CmdDispatch);
166 GET_DEVICE_PROC(CmdDispatchIndirect);
167 GET_DEVICE_PROC(CmdDraw);
168 GET_DEVICE_PROC(CmdDrawIndexed);
169 GET_DEVICE_PROC(CmdDrawIndexedIndirect);
170 GET_DEVICE_PROC(CmdDrawIndirect);
171 GET_DEVICE_PROC(CmdEndQuery);
172 GET_DEVICE_PROC(CmdEndRenderPass);
173 GET_DEVICE_PROC(CmdExecuteCommands);
174 GET_DEVICE_PROC(CmdFillBuffer);
175 GET_DEVICE_PROC(CmdNextSubpass);
176 GET_DEVICE_PROC(CmdPipelineBarrier);
177 GET_DEVICE_PROC(CmdPushConstants);
178 GET_DEVICE_PROC(CmdResetEvent);
179 GET_DEVICE_PROC(CmdResetQueryPool);
180 GET_DEVICE_PROC(CmdResolveImage);
181 GET_DEVICE_PROC(CmdSetBlendConstants);
182 GET_DEVICE_PROC(CmdSetDepthBias);
183 GET_DEVICE_PROC(CmdSetDepthBounds);
184 GET_DEVICE_PROC(CmdSetEvent);
185 GET_DEVICE_PROC(CmdSetLineWidth);
186 GET_DEVICE_PROC(CmdSetScissor);
187 GET_DEVICE_PROC(CmdSetStencilCompareMask);
188 GET_DEVICE_PROC(CmdSetStencilReference);
189 GET_DEVICE_PROC(CmdSetStencilWriteMask);
190 GET_DEVICE_PROC(CmdSetViewport);
191 GET_DEVICE_PROC(CmdUpdateBuffer);
192 GET_DEVICE_PROC(CmdWaitEvents);
193 GET_DEVICE_PROC(CmdWriteTimestamp);
194 GET_DEVICE_PROC(CreateBuffer);
195 GET_DEVICE_PROC(CreateBufferView);
196 GET_DEVICE_PROC(CreateCommandPool);
197 GET_DEVICE_PROC(CreateComputePipelines);
198 GET_DEVICE_PROC(CreateDescriptorPool);
199 GET_DEVICE_PROC(CreateDescriptorSetLayout);
200 GET_DEVICE_PROC(CreateEvent);
201 GET_DEVICE_PROC(CreateFence);
202 GET_DEVICE_PROC(CreateFramebuffer);
203 GET_DEVICE_PROC(CreateGraphicsPipelines);
204 GET_DEVICE_PROC(CreateImage);
205 GET_DEVICE_PROC(CreateImageView);
206 GET_DEVICE_PROC(CreatePipelineCache);
207 GET_DEVICE_PROC(CreatePipelineLayout);
208 GET_DEVICE_PROC(CreateQueryPool);
209 GET_DEVICE_PROC(CreateRenderPass);
210 GET_DEVICE_PROC(CreateSampler);
211 GET_DEVICE_PROC(CreateSemaphore);
212 GET_DEVICE_PROC(CreateShaderModule);
213 GET_DEVICE_PROC(DestroyBuffer);
214 GET_DEVICE_PROC(DestroyBufferView);
215 GET_DEVICE_PROC(DestroyCommandPool);
216 GET_DEVICE_PROC(DestroyDescriptorPool);
217 GET_DEVICE_PROC(DestroyDescriptorSetLayout);
218 GET_DEVICE_PROC(DestroyEvent);
219 GET_DEVICE_PROC(DestroyFence);
220 GET_DEVICE_PROC(DestroyFramebuffer);
221 GET_DEVICE_PROC(DestroyImage);
222 GET_DEVICE_PROC(DestroyImageView);
223 GET_DEVICE_PROC(DestroyPipeline);
224 GET_DEVICE_PROC(DestroyPipelineCache);
225 GET_DEVICE_PROC(DestroyPipelineLayout);
226 GET_DEVICE_PROC(DestroyQueryPool);
227 GET_DEVICE_PROC(DestroyRenderPass);
228 GET_DEVICE_PROC(DestroySampler);
229 GET_DEVICE_PROC(DestroySemaphore);
230 GET_DEVICE_PROC(DestroyShaderModule);
231 GET_DEVICE_PROC(DeviceWaitIdle);
232 GET_DEVICE_PROC(EndCommandBuffer);
233 GET_DEVICE_PROC(FlushMappedMemoryRanges);
234 GET_DEVICE_PROC(FreeCommandBuffers);
235 GET_DEVICE_PROC(FreeDescriptorSets);
236 GET_DEVICE_PROC(FreeMemory);
237 GET_DEVICE_PROC(GetBufferMemoryRequirements);
238 GET_DEVICE_PROC(GetDeviceMemoryCommitment);
239 GET_DEVICE_PROC(GetDeviceQueue);
240 GET_DEVICE_PROC(GetEventStatus);
241 GET_DEVICE_PROC(GetFenceStatus);
242 GET_DEVICE_PROC(GetImageMemoryRequirements);
243 GET_DEVICE_PROC(GetImageSparseMemoryRequirements);
244 GET_DEVICE_PROC(GetImageSubresourceLayout);
245 GET_DEVICE_PROC(GetPipelineCacheData);
246 GET_DEVICE_PROC(GetQueryPoolResults);
247 GET_DEVICE_PROC(GetRenderAreaGranularity);
248 GET_DEVICE_PROC(InvalidateMappedMemoryRanges);
249 GET_DEVICE_PROC(MapMemory);
250 GET_DEVICE_PROC(MergePipelineCaches);
251 GET_DEVICE_PROC(QueueBindSparse);
252 GET_DEVICE_PROC(QueueSubmit);
Zhenyao Modf9d1b52019-11-13 19:33:59 +0000253 {
254 // Hack to make using single queue on multiple threads safe.
255 g_native_vk_queue_submit_fn = QueueSubmit;
256 QueueSubmit = &vkQueueSubmit_ThreadSafe;
257 }
Corentin Wallez02162332017-11-21 12:52:03 -0500258 GET_DEVICE_PROC(QueueWaitIdle);
259 GET_DEVICE_PROC(ResetCommandBuffer);
260 GET_DEVICE_PROC(ResetCommandPool);
261 GET_DEVICE_PROC(ResetDescriptorPool);
262 GET_DEVICE_PROC(ResetEvent);
263 GET_DEVICE_PROC(ResetFences);
264 GET_DEVICE_PROC(SetEvent);
265 GET_DEVICE_PROC(UnmapMemory);
266 GET_DEVICE_PROC(UpdateDescriptorSets);
267 GET_DEVICE_PROC(WaitForFences);
268
Brandon Jones11d32c82019-02-20 20:21:00 +0000269 if (usedKnobs.debugMarker) {
270 GET_DEVICE_PROC(CmdDebugMarkerBeginEXT);
271 GET_DEVICE_PROC(CmdDebugMarkerEndEXT);
272 GET_DEVICE_PROC(CmdDebugMarkerInsertEXT);
273 }
274
Idan Raiteref4f3bd2019-08-02 18:10:38 +0000275 if (usedKnobs.externalMemoryFD) {
276 GET_DEVICE_PROC(GetMemoryFdKHR);
277 GET_DEVICE_PROC(GetMemoryFdPropertiesKHR);
278 }
279
280 if (usedKnobs.externalSemaphoreFD) {
281 GET_DEVICE_PROC(ImportSemaphoreFdKHR);
282 GET_DEVICE_PROC(GetSemaphoreFdKHR);
283 }
284
David 'Digit' Turnerfa00c692019-09-10 10:07:28 +0000285#if VK_USE_PLATFORM_FUCHSIA
286 if (usedKnobs.externalMemoryZirconHandle) {
287 GET_DEVICE_PROC(GetMemoryZirconHandleFUCHSIA);
288 GET_DEVICE_PROC(GetMemoryZirconHandlePropertiesFUCHSIA);
289 }
290
291 if (usedKnobs.externalSemaphoreZirconHandle) {
292 GET_DEVICE_PROC(ImportSemaphoreZirconHandleFUCHSIA);
293 GET_DEVICE_PROC(GetSemaphoreZirconHandleFUCHSIA);
294 }
295#endif
296
Corentin Wallez02162332017-11-21 12:52:03 -0500297 if (usedKnobs.swapchain) {
298 GET_DEVICE_PROC(CreateSwapchainKHR);
299 GET_DEVICE_PROC(DestroySwapchainKHR);
300 GET_DEVICE_PROC(GetSwapchainImagesKHR);
301 GET_DEVICE_PROC(AcquireNextImageKHR);
302 GET_DEVICE_PROC(QueuePresentKHR);
303 }
304
Corentin Wallez85df07a2018-12-03 12:49:56 +0000305 return {};
Corentin Wallez6d9a3b82017-11-20 10:51:23 -0500306 }
307
Corentin Wallez49a65d02018-07-24 16:45:45 +0200308}} // namespace dawn_native::vulkan