1 /*
2  * This file is part of libplacebo.
3  *
4  * libplacebo is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * libplacebo is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with libplacebo. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #pragma once
19 
20 #define VK_NO_PROTOTYPES
21 #include "../common.h"
22 #include "../log.h"
23 #include "../pl_thread.h"
24 
25 #ifdef PL_HAVE_WIN32
26 #include <windows.h>
27 #include <vulkan/vulkan_win32.h>
28 #endif
29 
30 // Vulkan allows the optional use of a custom allocator. We don't need one but
31 // mark this parameter with a better name in case we ever decide to change this
32 // in the future. (And to make the code more readable)
33 #define PL_VK_ALLOC NULL
34 
35 // Type of a vulkan function that needs to be loaded
36 #define PL_VK_FUN(name) PFN_vk##name name
37 
38 // Load a vulkan instance-level extension function directly (on the stack)
39 #define PL_VK_LOAD_FUN(inst, name, get_addr) \
40     PL_VK_FUN(name) = (PFN_vk##name) get_addr(inst, "vk" #name);
41 
42 // Hard-coded limit on the number of pending commands, to avoid OOM loops
43 #define PL_VK_MAX_QUEUED_CMDS 1024
44 #define PL_VK_MAX_PENDING_CMDS 1024
45 
46 // Shitty compatibility alias for very old vulkan.h versions
47 #ifndef VK_API_VERSION_1_2
48 #define VK_API_VERSION_1_2 VK_MAKE_VERSION(1, 2, 0)
49 #endif
50 
51 // Shared struct used to hold vulkan context information
52 struct vk_ctx {
53     pl_mutex lock;
54     void *alloc; // allocations bound to the lifetime of this vk_ctx
55     pl_vk_inst internal_instance;
56     pl_log log;
57     VkInstance inst;
58     VkPhysicalDevice physd;
59     VkPhysicalDeviceLimits limits;
60     VkPhysicalDeviceFeatures2 features;
61     uint32_t api_ver; // device API version
62     VkDevice dev;
63     bool imported; // device was not created by us
64 
65     // Generic error flag for catching "failed" devices
66     bool failed;
67 
68     // Enabled extensions
69     PL_ARRAY(const char *) exts;
70 
71     // Command pools (one per queue family)
72     PL_ARRAY(struct vk_cmdpool *) pools;
73 
74     // Pointers into `pools`
75     struct vk_cmdpool *pool_graphics; // required
76     struct vk_cmdpool *pool_compute;  // optional
77     struct vk_cmdpool *pool_transfer; // optional
78 
79     // Queued/pending commands. These are shared for the entire mpvk_ctx to
80     // ensure submission and callbacks are FIFO
81     PL_ARRAY(struct vk_cmd *) cmds_queued;  // recorded but not yet submitted
82     PL_ARRAY(struct vk_cmd *) cmds_pending; // submitted but not completed
83 
84     // A dynamic reference to the most recently submitted command that has not
85     // yet completed. Used to implement vk_dev_callback. Gets cleared when
86     // the command completes.
87     struct vk_cmd *last_cmd;
88 
89     // Common pool of signals, to avoid having to re-create these objects often
90     PL_ARRAY(struct vk_signal *) signals;
91     bool disable_events;
92 
93     // Instance-level function pointers
94     PL_VK_FUN(CreateDevice);
95     PL_VK_FUN(EnumerateDeviceExtensionProperties);
96     PL_VK_FUN(GetDeviceProcAddr);
97     PL_VK_FUN(GetInstanceProcAddr);
98     PL_VK_FUN(GetPhysicalDeviceExternalBufferProperties);
99     PL_VK_FUN(GetPhysicalDeviceExternalSemaphoreProperties);
100     PL_VK_FUN(GetPhysicalDeviceFeatures2KHR);
101     PL_VK_FUN(GetPhysicalDeviceFormatProperties);
102     PL_VK_FUN(GetPhysicalDeviceFormatProperties2KHR);
103     PL_VK_FUN(GetPhysicalDeviceImageFormatProperties2KHR);
104     PL_VK_FUN(GetPhysicalDeviceMemoryProperties);
105     PL_VK_FUN(GetPhysicalDeviceProperties);
106     PL_VK_FUN(GetPhysicalDeviceProperties2);
107     PL_VK_FUN(GetPhysicalDeviceQueueFamilyProperties);
108     PL_VK_FUN(GetPhysicalDeviceSurfaceCapabilitiesKHR);
109     PL_VK_FUN(GetPhysicalDeviceSurfaceFormatsKHR);
110     PL_VK_FUN(GetPhysicalDeviceSurfacePresentModesKHR);
111     PL_VK_FUN(GetPhysicalDeviceSurfaceSupportKHR);
112 
113     // Device-level function pointers
114     PL_VK_FUN(AcquireNextImageKHR);
115     PL_VK_FUN(AllocateCommandBuffers);
116     PL_VK_FUN(AllocateDescriptorSets);
117     PL_VK_FUN(AllocateMemory);
118     PL_VK_FUN(BeginCommandBuffer);
119     PL_VK_FUN(BindBufferMemory);
120     PL_VK_FUN(BindImageMemory);
121     PL_VK_FUN(CmdBeginDebugUtilsLabelEXT);
122     PL_VK_FUN(CmdBeginRenderPass);
123     PL_VK_FUN(CmdBindDescriptorSets);
124     PL_VK_FUN(CmdBindIndexBuffer);
125     PL_VK_FUN(CmdBindPipeline);
126     PL_VK_FUN(CmdBindVertexBuffers);
127     PL_VK_FUN(CmdBlitImage);
128     PL_VK_FUN(CmdClearColorImage);
129     PL_VK_FUN(CmdCopyBuffer);
130     PL_VK_FUN(CmdCopyBufferToImage);
131     PL_VK_FUN(CmdCopyImage);
132     PL_VK_FUN(CmdCopyImageToBuffer);
133     PL_VK_FUN(CmdDispatch);
134     PL_VK_FUN(CmdDraw);
135     PL_VK_FUN(CmdDrawIndexed);
136     PL_VK_FUN(CmdEndDebugUtilsLabelEXT);
137     PL_VK_FUN(CmdEndRenderPass);
138     PL_VK_FUN(CmdPipelineBarrier);
139     PL_VK_FUN(CmdPushConstants);
140     PL_VK_FUN(CmdPushDescriptorSetKHR);
141     PL_VK_FUN(CmdResetQueryPool);
142     PL_VK_FUN(CmdSetEvent);
143     PL_VK_FUN(CmdSetScissor);
144     PL_VK_FUN(CmdSetViewport);
145     PL_VK_FUN(CmdUpdateBuffer);
146     PL_VK_FUN(CmdWaitEvents);
147     PL_VK_FUN(CmdWriteTimestamp);
148     PL_VK_FUN(CreateBuffer);
149     PL_VK_FUN(CreateBufferView);
150     PL_VK_FUN(CreateCommandPool);
151     PL_VK_FUN(CreateComputePipelines);
152     PL_VK_FUN(CreateDebugReportCallbackEXT);
153     PL_VK_FUN(CreateDescriptorPool);
154     PL_VK_FUN(CreateDescriptorSetLayout);
155     PL_VK_FUN(CreateEvent);
156     PL_VK_FUN(CreateFence);
157     PL_VK_FUN(CreateFramebuffer);
158     PL_VK_FUN(CreateGraphicsPipelines);
159     PL_VK_FUN(CreateImage);
160     PL_VK_FUN(CreateImageView);
161     PL_VK_FUN(CreatePipelineCache);
162     PL_VK_FUN(CreatePipelineLayout);
163     PL_VK_FUN(CreateQueryPool);
164     PL_VK_FUN(CreateRenderPass);
165     PL_VK_FUN(CreateSampler);
166     PL_VK_FUN(CreateSemaphore);
167     PL_VK_FUN(CreateShaderModule);
168     PL_VK_FUN(CreateSwapchainKHR);
169     PL_VK_FUN(DestroyBuffer);
170     PL_VK_FUN(DestroyBufferView);
171     PL_VK_FUN(DestroyCommandPool);
172     PL_VK_FUN(DestroyDebugReportCallbackEXT);
173     PL_VK_FUN(DestroyDescriptorPool);
174     PL_VK_FUN(DestroyDescriptorSetLayout);
175     PL_VK_FUN(DestroyDevice);
176     PL_VK_FUN(DestroyEvent);
177     PL_VK_FUN(DestroyFence);
178     PL_VK_FUN(DestroyFramebuffer);
179     PL_VK_FUN(DestroyImage);
180     PL_VK_FUN(DestroyImageView);
181     PL_VK_FUN(DestroyInstance);
182     PL_VK_FUN(DestroyPipeline);
183     PL_VK_FUN(DestroyPipelineCache);
184     PL_VK_FUN(DestroyPipelineLayout);
185     PL_VK_FUN(DestroyQueryPool);
186     PL_VK_FUN(DestroyRenderPass);
187     PL_VK_FUN(DestroySampler);
188     PL_VK_FUN(DestroySemaphore);
189     PL_VK_FUN(DestroyShaderModule);
190     PL_VK_FUN(DestroySwapchainKHR);
191     PL_VK_FUN(EndCommandBuffer);
192     PL_VK_FUN(FlushMappedMemoryRanges);
193     PL_VK_FUN(FreeCommandBuffers);
194     PL_VK_FUN(FreeMemory);
195     PL_VK_FUN(GetBufferMemoryRequirements);
196     PL_VK_FUN(GetDeviceQueue);
197     PL_VK_FUN(GetImageDrmFormatModifierPropertiesEXT);
198     PL_VK_FUN(GetImageMemoryRequirements2);
199     PL_VK_FUN(GetImageSubresourceLayout);
200     PL_VK_FUN(GetMemoryFdKHR);
201     PL_VK_FUN(GetMemoryFdPropertiesKHR);
202     PL_VK_FUN(GetMemoryHostPointerPropertiesEXT);
203     PL_VK_FUN(GetPipelineCacheData);
204     PL_VK_FUN(GetQueryPoolResults);
205     PL_VK_FUN(GetSemaphoreFdKHR);
206     PL_VK_FUN(GetSwapchainImagesKHR);
207     PL_VK_FUN(InvalidateMappedMemoryRanges);
208     PL_VK_FUN(MapMemory);
209     PL_VK_FUN(QueuePresentKHR);
210     PL_VK_FUN(QueueSubmit);
211     PL_VK_FUN(ResetEvent);
212     PL_VK_FUN(ResetFences);
213     PL_VK_FUN(ResetQueryPoolEXT);
214     PL_VK_FUN(SetDebugUtilsObjectNameEXT);
215     PL_VK_FUN(SetHdrMetadataEXT);
216     PL_VK_FUN(UpdateDescriptorSets);
217     PL_VK_FUN(WaitForFences);
218 
219 #ifdef PL_HAVE_WIN32
220     PL_VK_FUN(GetMemoryWin32HandleKHR);
221     PL_VK_FUN(GetSemaphoreWin32HandleKHR);
222 #endif
223 };
224