]> git.tdb.fi Git - libs/gl.git/blob - source/backends/vulkan/vulkan.h
Support compute shaders and compute operations
[libs/gl.git] / source / backends / vulkan / vulkan.h
1 #ifndef MSP_GL_VULKAN_H_
2 #define MSP_GL_VULKAN_H_
3
4 #include <vulkan/vulkan.h>
5 #include <msp/graphics/vulkancontext.h>
6 #include "handles.h"
7
8 namespace Msp {
9 namespace GL {
10
11 template<typename T> struct HandleTraits;
12 template<> struct HandleTraits<VkBuffer> { using NativeHandle = ::VkBuffer; };
13 template<> struct HandleTraits<::VkBuffer> { using Wrapper = VkBuffer; };
14 template<> struct HandleTraits<VkCommandBuffer> { using NativeHandle = ::VkCommandBuffer; };
15 template<> struct HandleTraits<::VkCommandBuffer> { using Wrapper = VkCommandBuffer; };
16 template<> struct HandleTraits<VkCommandPool> { using NativeHandle = ::VkCommandPool; };
17 template<> struct HandleTraits<::VkCommandPool> { using Wrapper = VkCommandPool; };
18 template<> struct HandleTraits<VkDevice> { using NativeHandle = ::VkDevice; };
19 template<> struct HandleTraits<::VkDevice> { using Wrapper = VkDevice; };
20 template<> struct HandleTraits<VkDescriptorPool> { using NativeHandle = ::VkDescriptorPool; };
21 template<> struct HandleTraits<::VkDescriptorPool> { using Wrapper = VkDescriptorPool; };
22 template<> struct HandleTraits<VkDescriptorSet> { using NativeHandle = ::VkDescriptorSet; };
23 template<> struct HandleTraits<::VkDescriptorSet> { using Wrapper = VkDescriptorSet; };
24 template<> struct HandleTraits<VkDescriptorSetLayout> { using NativeHandle = ::VkDescriptorSetLayout; };
25 template<> struct HandleTraits<::VkDescriptorSetLayout> { using Wrapper = VkDescriptorSetLayout; };
26 template<> struct HandleTraits<VkDeviceMemory> { using NativeHandle = ::VkDeviceMemory; };
27 template<> struct HandleTraits<::VkDeviceMemory> { using Wrapper = VkDeviceMemory; };
28 template<> struct HandleTraits<VkFence> { using NativeHandle = ::VkFence; };
29 template<> struct HandleTraits<::VkFence> { using Wrapper = VkFence; };
30 template<> struct HandleTraits<VkFramebuffer> { using NativeHandle = ::VkFramebuffer; };
31 template<> struct HandleTraits<::VkFramebuffer> { using Wrapper = VkFramebuffer; };
32 template<> struct HandleTraits<VkImage> { using NativeHandle = ::VkImage; };
33 template<> struct HandleTraits<::VkImage> { using Wrapper = VkImage; };
34 template<> struct HandleTraits<VkImageView> { using NativeHandle = ::VkImageView; };
35 template<> struct HandleTraits<::VkImageView> { using Wrapper = VkImageView; };
36 template<> struct HandleTraits<VkPhysicalDevice> { using NativeHandle = ::VkPhysicalDevice; };
37 template<> struct HandleTraits<::VkPhysicalDevice> { using Wrapper = VkPhysicalDevice; };
38 template<> struct HandleTraits<VkPipeline> { using NativeHandle = ::VkPipeline; };
39 template<> struct HandleTraits<::VkPipeline> { using Wrapper = VkPipeline; };
40 template<> struct HandleTraits<VkPipelineCache> { using NativeHandle = ::VkPipelineCache; };
41 template<> struct HandleTraits<::VkPipelineCache> { using Wrapper = VkPipelineCache; };
42 template<> struct HandleTraits<VkPipelineLayout> { using NativeHandle = ::VkPipelineLayout; };
43 template<> struct HandleTraits<::VkPipelineLayout> { using Wrapper = VkPipelineLayout; };
44 template<> struct HandleTraits<VkQueue> { using NativeHandle = ::VkQueue; };
45 template<> struct HandleTraits<::VkQueue> { using Wrapper = VkQueue; };
46 template<> struct HandleTraits<VkRenderPass> { using NativeHandle = ::VkRenderPass; };
47 template<> struct HandleTraits<::VkRenderPass> { using Wrapper = VkRenderPass; };
48 template<> struct HandleTraits<VkSampler> { using NativeHandle = ::VkSampler; };
49 template<> struct HandleTraits<::VkSampler> { using Wrapper = VkSampler; };
50 template<> struct HandleTraits<VkSemaphore> { using NativeHandle = ::VkSemaphore; };
51 template<> struct HandleTraits<::VkSemaphore> { using Wrapper = VkSemaphore; };
52 template<> struct HandleTraits<VkShaderModule> { using NativeHandle = ::VkShaderModule; };
53 template<> struct HandleTraits<::VkShaderModule> { using Wrapper = VkShaderModule; };
54 template<> struct HandleTraits<VkSurface> { using NativeHandle = ::VkSurfaceKHR; };
55 template<> struct HandleTraits<::VkSurfaceKHR> { using Wrapper = VkSurface; };
56 template<> struct HandleTraits<VkSwapchain> { using NativeHandle = ::VkSwapchainKHR; };
57 template<> struct HandleTraits<::VkSwapchainKHR> { using Wrapper = VkSwapchain; };
58
59 template<typename T>
60 T handle_cast(typename HandleTraits<T>::Wrapper handle)
61 { return reinterpret_cast<T>(handle); }
62
63 template<typename T>
64 T handle_cast(typename HandleTraits<T>::NativeHandle handle)
65 { return reinterpret_cast<T>(handle); }
66
67 template<typename T>
68 T handle_cast(typename HandleTraits<typename std::remove_pointer<T>::type>::Wrapper *handle)
69 { return reinterpret_cast<T>(handle); }
70
71 template<typename T>
72 T handle_cast(const typename HandleTraits<typename std::remove_const<typename std::remove_pointer<T>::type>::type>::Wrapper *handle)
73 { return reinterpret_cast<T>(handle); }
74
75
76 class Result
77 {
78 private:
79         VkResult result;
80         const char *function;
81         bool checked = false;
82
83 public:
84         Result(VkResult r, const char *f): result(r), function(f) { }
85         Result(Result &&r): result(r.result), function(r.function) { r.result = VK_SUCCESS; }
86         ~Result() noexcept(false) { if(!checked) check(); }
87
88         bool operator==(VkResult r) { bool m = (result==r); checked |= m; return m; }
89         void check() { if(result!=VK_SUCCESS) throw Graphics::vulkan_error(result, function); }
90 };
91
92
93 class VulkanFunctions
94 {
95 private:
96         const Graphics::VulkanContext &context;
97         ::VkDevice device;
98         ::VkPhysicalDevice physicalDevice;
99         ::VkQueue graphicsQueue;
100
101         PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties = 0;  // 5.1
102         PFN_vkCreateCommandPool vkCreateCommandPool = 0;  // 6.2
103         PFN_vkResetCommandPool vkResetCommandPool = 0;  // 6.2
104         PFN_vkDestroyCommandPool vkDestroyCommandPool = 0;  // 6.2
105         PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers = 0;  // 6.3
106         PFN_vkBeginCommandBuffer vkBeginCommandBuffer = 0;  // 6.4
107         PFN_vkEndCommandBuffer vkEndCommandBuffer = 0;  // 6.4
108         PFN_vkQueueSubmit vkQueueSubmit = 0;  // 6.5
109         PFN_vkCmdExecuteCommands vkCmdExecuteCommands = 0;  // 6.7
110         PFN_vkCreateFence vkCreateFence = 0;  // 7.3
111         PFN_vkDestroyFence vkDestroyFence = 0;  // 7.3
112         PFN_vkGetFenceStatus vkGetFenceStatus = 0;  // 7.3
113         PFN_vkResetFences vkResetFences = 0;  // 7.3
114         PFN_vkWaitForFences vkWaitForFences = 0;  // 7.3
115         PFN_vkCreateSemaphore vkCreateSemaphore = 0;  // 7.4
116         PFN_vkDestroySemaphore vkDestroySemaphore = 0;  // 7.4
117         PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier = 0;  // 7.6
118         PFN_vkQueueWaitIdle vkQueueWaitIdle = 0;  // 7.8
119         PFN_vkCreateRenderPass vkCreateRenderPass = 0;  // 8.1
120         PFN_vkDestroyRenderPass vkDestroyRenderPass = 0;  // 8.1
121         PFN_vkCreateFramebuffer vkCreateFramebuffer = 0;  // 8.3
122         PFN_vkDestroyFramebuffer vkDestroyFramebuffer = 0;  // 8.3
123         PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass = 0;  // 8.4
124         PFN_vkCmdEndRenderPass vkCmdEndRenderPass = 0;  // 8.4
125         PFN_vkCreateShaderModule vkCreateShaderModule = 0;  // 9.1
126         PFN_vkDestroyShaderModule vkDestroyShaderModule = 0;  // 9.1
127         PFN_vkCreateComputePipelines vkCreateComputePipelines = 0;  // 10.1
128         PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines = 0;  // 10.2
129         PFN_vkDestroyPipeline vkDestroyPipeline = 0;  // 10.4
130         PFN_vkCmdBindPipeline vkCmdBindPipeline = 0;  // 10.10
131         PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties = 0;  // 11.2.1
132         PFN_vkAllocateMemory vkAllocateMemory = 0;  // 11.2.3
133         PFN_vkFreeMemory vkFreeMemory = 0;  // 11.2.8
134         PFN_vkMapMemory vkMapMemory = 0;  // 11.2.9
135         PFN_vkUnmapMemory vkUnmapMemory = 0;  // 11.2.9
136         PFN_vkCreateBuffer vkCreateBuffer = 0;  // 12.1
137         PFN_vkDestroyBuffer vkDestroyBuffer = 0;  // 12.1
138         PFN_vkCreateImage vkCreateImage = 0;  // 12.3
139         PFN_vkDestroyImage vkDestroyImage = 0;  // 12.3
140         PFN_vkCreateImageView vkCreateImageView = 0;  // 12.5
141         PFN_vkDestroyImageView vkDestroyImageView = 0;  // 12.5
142         PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements = 0;  // 12.7
143         PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements = 0;  // 12.7
144         PFN_vkBindBufferMemory vkBindBufferMemory = 0;  // 12.7
145         PFN_vkBindImageMemory vkBindImageMemory = 0;  // 12.7
146         PFN_vkCreateSampler vkCreateSampler = 0;  // 13
147         PFN_vkDestroySampler vkDestroySampler = 0;  // 13
148         PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout = 0;  // 14.2.1
149         PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout = 0;  // 14.2.1
150         PFN_vkCreatePipelineLayout vkCreatePipelineLayout = 0;  // 14.2.2
151         PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout = 0;  // 14.2.2
152         PFN_vkCreateDescriptorPool vkCreateDescriptorPool = 0;  // 14.2.3
153         PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool = 0;  // 14.2.3
154         PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets = 0;  // 14.2.3
155         PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets = 0;  // 14.2.4
156         PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets = 0;  // 14.2.7
157         PFN_vkCmdPushConstants vkCmdPushConstants = 0;  // 14.2.10
158         PFN_vkCmdCopyBuffer vkCmdCopyBuffer = 0;  // 19.2
159         PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage = 0;  // 19.4
160         PFN_vkCmdBlitImage vkCmdBlitImage = 0;  // 19.5
161         PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer = 0;  // 20.3
162         PFN_vkCmdDrawIndexed vkCmdDrawIndexed = 0;  // 20.3
163         PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers = 0;  // 21.2
164         PFN_vkCmdSetViewport vkCmdSetViewport = 0;  // 24.5
165         PFN_vkCmdSetScissor vkCmdSetScissor = 0;  // 26.1
166         PFN_vkCmdDispatch vkCmdDispatch = 0;  // 28
167         PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilities = 0;  // 30.5.1
168         PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormats = 0;  // 30.5.2
169         PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModes = 0;  // 30.5.3
170         PFN_vkCreateSwapchainKHR vkCreateSwapchain = 0;  // 30.8
171         PFN_vkDestroySwapchainKHR vkDestroySwapchain = 0;  // 30.8
172         PFN_vkGetSwapchainImagesKHR vkGetSwapchainImages = 0;  // 30.8
173         PFN_vkAcquireNextImageKHR vkAcquireNextImage = 0;  // 30.8
174         PFN_vkQueuePresentKHR vkQueuePresent = 0;  // 30.8
175         PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties = 0;  // 39.2
176         PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectName = 0;  // 45.1.1
177
178 public:
179         VulkanFunctions(const Graphics::VulkanContext &);
180
181         // Chapter 5: Devices and Queues
182         void GetPhysicalDeviceProperties(VkPhysicalDeviceProperties &rProperties) const
183         { vkGetPhysicalDeviceProperties(physicalDevice, &rProperties); }
184
185         // Chapter 6: Command Buffers
186         Result CreateCommandPool(const VkCommandPoolCreateInfo &rCreateInfo, VkCommandPool &rCommandPool) const
187         { return { vkCreateCommandPool(device, &rCreateInfo, 0, handle_cast<::VkCommandPool *>(&rCommandPool)), "vkCreateCommandPool" }; }
188
189         Result ResetCommandPool(VkCommandPool commandPool, VkCommandPoolResetFlags flags) const
190         { return { vkResetCommandPool(device, handle_cast<::VkCommandPool>(commandPool), flags), "vkResetCommandPool" }; }
191
192         void DestroyCommandPool(VkCommandPool commandPool) const
193         { vkDestroyCommandPool(device, handle_cast<::VkCommandPool>(commandPool), 0); }
194
195         Result AllocateCommandBuffers(const VkCommandBufferAllocateInfo &rAllocateInfo, VkCommandBuffer *pCommandBuffers) const
196         { return { vkAllocateCommandBuffers(device, &rAllocateInfo, handle_cast<::VkCommandBuffer *>(pCommandBuffers)), "vkAllocateCommandBuffers" }; }
197
198         Result BeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo &rBeginInfo) const
199         { return { vkBeginCommandBuffer(handle_cast<::VkCommandBuffer>(commandBuffer), &rBeginInfo), "vkBeginCommandBuffer" }; }
200
201         Result EndCommandBuffer(VkCommandBuffer commandBuffer) const
202         { return { vkEndCommandBuffer(handle_cast<::VkCommandBuffer>(commandBuffer)), "vkEndCommandBuffer" }; }
203
204         Result QueueSubmit(std::uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) const
205         { return { vkQueueSubmit(graphicsQueue, submitCount, pSubmits, handle_cast<::VkFence>(fence)), "vkQueueSubmit" }; }
206
207         void CmdExecuteCommands(VkCommandBuffer commandBuffer, std::uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers) const
208         { vkCmdExecuteCommands(handle_cast<::VkCommandBuffer>(commandBuffer), commandBufferCount, handle_cast<const ::VkCommandBuffer *>(pCommandBuffers)); }
209
210         // Chapter 7: Synchronization and Cache Control
211         Result CreateFence(const VkFenceCreateInfo &rCreateInfo, VkFence &rFence) const
212         { return { vkCreateFence(device, &rCreateInfo, 0, handle_cast<::VkFence *>(&rFence)), "vkCreateFence" }; }
213
214         void DestroyFence(VkFence fence) const
215         { vkDestroyFence(device, handle_cast<::VkFence>(fence), 0); }
216
217         Result GetFenceStatus(VkFence fence) const
218         { return { vkGetFenceStatus(device, handle_cast<::VkFence>(fence)), "vkGetFenceStatus" }; }
219
220         Result ResetFences(std::uint32_t fenceCount, const VkFence *pFences) const
221         { return { vkResetFences(device, fenceCount, handle_cast<const ::VkFence *>(pFences)), "vkResetFences" }; }
222
223         Result WaitForFences(std::uint32_t fenceCount, const VkFence *pFences, VkBool32 waitAll, std::uint64_t timeout) const
224         { return { vkWaitForFences(device, fenceCount, handle_cast<const ::VkFence *>(pFences), waitAll, timeout), "vkWaitForFences" }; }
225
226         Result CreateSemaphore(const VkSemaphoreCreateInfo &rCreateInfo, VkSemaphore &rSemaphore) const
227         { return { vkCreateSemaphore(device, &rCreateInfo, 0, handle_cast<::VkSemaphore *>(&rSemaphore)), "vkCreateSemaphore" }; }
228
229         void DestroySemaphore(VkSemaphore semaphore) const
230         { vkDestroySemaphore(device, handle_cast<::VkSemaphore>(semaphore), 0); }
231
232         void CmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) const
233         { vkCmdPipelineBarrier(handle_cast<::VkCommandBuffer>(commandBuffer), srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers); }
234
235         Result QueueWaitIdle() const
236         { return { vkQueueWaitIdle(graphicsQueue), "vkQueueWaitIdle" }; }
237
238         // Chapter 8: Render Pass
239         Result CreateRenderPass(const VkRenderPassCreateInfo &rCreateInfo, VkRenderPass &rRenderPass) const
240         { return { vkCreateRenderPass(device, &rCreateInfo, 0, handle_cast<::VkRenderPass *>(&rRenderPass)), "vkCreateRenderPass" }; }
241
242         void DestroyRenderPass(VkRenderPass renderPass) const
243         { vkDestroyRenderPass(device, handle_cast<::VkRenderPass>(renderPass), 0); }
244
245         Result CreateFramebuffer(const VkFramebufferCreateInfo &rCreateInfo, VkFramebuffer &rFramebuffer) const
246         { return { vkCreateFramebuffer(device, &rCreateInfo, 0, handle_cast<::VkFramebuffer *>(&rFramebuffer)), "vkCreateFramebuffer" }; }
247
248         void DestroyFramebuffer(VkFramebuffer framebuffer) const
249         { vkDestroyFramebuffer(device, handle_cast<::VkFramebuffer>(framebuffer), 0); }
250
251         void CmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo &rRenderPassBegin, VkSubpassContents contents) const
252         { vkCmdBeginRenderPass(handle_cast<::VkCommandBuffer>(commandBuffer), &rRenderPassBegin, contents); }
253
254         void CmdEndRenderPass(VkCommandBuffer commandBuffer) const
255         { vkCmdEndRenderPass(handle_cast<::VkCommandBuffer>(commandBuffer)); }
256
257         // Chapter 9: Shaders
258         Result CreateShaderModule(const VkShaderModuleCreateInfo &rCreateInfo, VkShaderModule &rShaderModule) const
259         { return { vkCreateShaderModule(device, &rCreateInfo, 0, handle_cast<::VkShaderModule *>(&rShaderModule)), "vkCreateShaderModule" }; }
260
261         void DestroyShaderModule(VkShaderModule shaderModule) const
262         { vkDestroyShaderModule(device, handle_cast<::VkShaderModule>(shaderModule), 0); }
263
264         // Chapter 10: Pipelines
265         Result CreateComputePipelines(VkPipelineCache pipelineCache, std::uint32_t createInfoCount, const VkComputePipelineCreateInfo *pCreateInfos, VkPipeline *pPipelines) const
266         { return { vkCreateComputePipelines(device, handle_cast<::VkPipelineCache>(pipelineCache), createInfoCount, pCreateInfos, 0, handle_cast<::VkPipeline *>(pPipelines)), "vkCreateComputePipelines" }; }
267
268         Result CreateGraphicsPipelines(VkPipelineCache pipelineCache, std::uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo *pCreateInfos, VkPipeline *pPipelines) const
269         { return { vkCreateGraphicsPipelines(device, handle_cast<::VkPipelineCache>(pipelineCache), createInfoCount, pCreateInfos, 0, handle_cast<::VkPipeline *>(pPipelines)), "vkCreateGraphicsPipelines" }; }
270
271         void DestroyPipeline(VkPipeline pipeline) const
272         { vkDestroyPipeline(device, handle_cast<::VkPipeline>(pipeline), 0); }
273
274         void CmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline) const
275         { vkCmdBindPipeline(handle_cast<::VkCommandBuffer>(commandBuffer), pipelineBindPoint, handle_cast<::VkPipeline>(pipeline)); }
276
277         // Chapter 11: Memory Allocation
278         void GetPhysicalDeviceMemoryProperties(VkPhysicalDeviceMemoryProperties &rMemoryProperties) const
279         { vkGetPhysicalDeviceMemoryProperties(physicalDevice, &rMemoryProperties); }
280
281         Result AllocateMemory(const VkMemoryAllocateInfo &rAllocateInfo, VkDeviceMemory &rMemory) const
282         { return { vkAllocateMemory(device, &rAllocateInfo, 0, handle_cast<::VkDeviceMemory *>(&rMemory)), "vkAllocateMemory" }; }
283
284         Result MapMemory(VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void **ppData) const
285         { return { vkMapMemory(device, handle_cast<::VkDeviceMemory>(memory), offset, size, flags, ppData), "vkMapMemory" }; }
286
287         void UnmapMemory(VkDeviceMemory memory) const
288         { vkUnmapMemory(device, handle_cast<::VkDeviceMemory>(memory)); }
289
290         void FreeMemory(VkDeviceMemory memory) const
291         { vkFreeMemory(device, handle_cast<::VkDeviceMemory>(memory), 0); }
292
293         // Chapter 12: Resource Creation
294         Result CreateBuffer(const VkBufferCreateInfo &rCreateInfo, VkBuffer &rBuffer) const
295         { return { vkCreateBuffer(device, &rCreateInfo, 0, handle_cast<::VkBuffer *>(&rBuffer)), "vkCreateBuffer" }; }
296
297         void DestroyBuffer(VkBuffer image) const
298         { vkDestroyBuffer(device, handle_cast<::VkBuffer>(image), 0); }
299
300         Result CreateImage(const VkImageCreateInfo &rCreateInfo, VkImage &rImage) const
301         { return { vkCreateImage(device, &rCreateInfo, 0, handle_cast<::VkImage *>(&rImage)), "vkCreateImage" }; }
302
303         void DestroyImage(VkImage image) const
304         { vkDestroyImage(device, handle_cast<::VkImage>(image), 0); }
305
306         Result CreateImageView(const VkImageViewCreateInfo &rCreateInfo, VkImageView &rView) const
307         { return { vkCreateImageView(device, &rCreateInfo, 0, handle_cast<::VkImageView *>(&rView)), "vkCreateImageView" }; }
308
309         void DestroyImageView(VkImageView imageView) const
310         { vkDestroyImageView(device, handle_cast<::VkImageView>(imageView), 0); }
311
312         void GetBufferMemoryRequirements(VkBuffer image, VkMemoryRequirements &rMemoryRequirements) const
313         { vkGetBufferMemoryRequirements(device, handle_cast<::VkBuffer>(image), &rMemoryRequirements); }
314
315         void GetImageMemoryRequirements(VkImage image, VkMemoryRequirements &rMemoryRequirements) const
316         { vkGetImageMemoryRequirements(device, handle_cast<::VkImage>(image), &rMemoryRequirements); }
317
318         Result BindBufferMemory(VkBuffer image, VkDeviceMemory memory, VkDeviceSize memoryOffset) const
319         { return { vkBindBufferMemory(device, handle_cast<::VkBuffer>(image), handle_cast<::VkDeviceMemory>(memory), memoryOffset), "vkBindBufferMemory" }; }
320
321         Result BindImageMemory(VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset) const
322         { return { vkBindImageMemory(device, handle_cast<::VkImage>(image), handle_cast<::VkDeviceMemory>(memory), memoryOffset), "vkBindImageMemory" }; }
323
324         // Chapter 13: Samplers
325         Result CreateSampler(const VkSamplerCreateInfo &rCreateInfo, VkSampler &rSampler) const
326         { return { vkCreateSampler(device, &rCreateInfo, 0, handle_cast<::VkSampler *>(&rSampler)), "vkCreateSampler" }; }
327
328         void DestroySampler(VkSampler sampler) const
329         { vkDestroySampler(device, handle_cast<::VkSampler>(sampler), 0); }
330
331         // Chapter 14: Resource Descriptors
332         Result CreateDescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo &rCreateInfo, VkDescriptorSetLayout &rSetLayout) const
333         { return { vkCreateDescriptorSetLayout(device, &rCreateInfo, 0, handle_cast<::VkDescriptorSetLayout *>(&rSetLayout)), "vkCreateDescriptorSetLayout" }; }
334
335         void DestroyDescriptorSetLayout(VkDescriptorSetLayout descriptorSetLayout) const
336         { vkDestroyDescriptorSetLayout(device, handle_cast<::VkDescriptorSetLayout>(descriptorSetLayout), 0); }
337
338         Result CreatePipelineLayout(const VkPipelineLayoutCreateInfo &rCreateInfo, VkPipelineLayout &rPipelineLayout) const
339         { return { vkCreatePipelineLayout(device, &rCreateInfo, 0, handle_cast<::VkPipelineLayout *>(&rPipelineLayout)), "vkCreatePipelineLayout" }; }
340
341         void DestroyPipelineLayout(VkPipelineLayout pipelineLayout) const
342         { vkDestroyPipelineLayout(device, handle_cast<::VkPipelineLayout>(pipelineLayout), 0); }
343
344         Result CreateDescriptorPool(const VkDescriptorPoolCreateInfo &rCreateInfo, VkDescriptorPool &rDescriptorPool) const
345         { return { vkCreateDescriptorPool(device, &rCreateInfo, 0, handle_cast<::VkDescriptorPool *>(&rDescriptorPool)), "vkCreateDescriptorPool" }; }
346
347         void DestroyDescriptorPool(VkDescriptorPool descriptorPool) const
348         { vkDestroyDescriptorPool(device, handle_cast<::VkDescriptorPool>(descriptorPool), 0); }
349
350         Result AllocateDescriptorSets(const VkDescriptorSetAllocateInfo &rAllocateInfo, VkDescriptorSet *pDescriptorSets) const
351         { return { vkAllocateDescriptorSets(device, &rAllocateInfo, handle_cast<::VkDescriptorSet *>(pDescriptorSets)), "vkAllocateDescriptorSets" }; }
352
353         void UpdateDescriptorSets(std::uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites, std::uint32_t descriptorCopyCount, const VkCopyDescriptorSet *pDescriptorCopies) const
354         { vkUpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, pDescriptorCopies); }
355
356         void CmdBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, std::uint32_t firstSet, std::uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets, std::uint32_t dynamicOffsetCount, const std::uint32_t *pDynamicOffsets) const
357         { vkCmdBindDescriptorSets(handle_cast<::VkCommandBuffer>(commandBuffer), pipelineBindPoint, handle_cast<::VkPipelineLayout>(layout), firstSet, descriptorSetCount, handle_cast<const ::VkDescriptorSet *>(pDescriptorSets), dynamicOffsetCount, pDynamicOffsets); }
358
359         void CmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, std::uint32_t offset, std::uint32_t size, const void *pValues) const
360         { vkCmdPushConstants(handle_cast<::VkCommandBuffer>(commandBuffer), handle_cast<::VkPipelineLayout>(layout), stageFlags, offset, size, pValues); }
361
362         // Chapter 19: Copy Commands
363         void CmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, std::uint32_t regionCount, const VkBufferCopy *pRegions) const
364         { vkCmdCopyBuffer(handle_cast<::VkCommandBuffer>(commandBuffer), handle_cast<::VkBuffer>(srcBuffer), handle_cast<::VkBuffer>(dstBuffer), regionCount, pRegions); }
365
366         void CmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, std::uint32_t regionCount, const VkBufferImageCopy *pRegions) const
367         { vkCmdCopyBufferToImage(handle_cast<::VkCommandBuffer>(commandBuffer), handle_cast<::VkBuffer>(srcBuffer), handle_cast<::VkImage>(dstImage), dstImageLayout, regionCount, pRegions); }
368
369         void CmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit *pRegions, VkFilter filter) const
370         { vkCmdBlitImage(handle_cast<::VkCommandBuffer>(commandBuffer), handle_cast<::VkImage>(srcImage), srcImageLayout, handle_cast<::VkImage>(dstImage), dstImageLayout, regionCount, pRegions, filter); }
371
372         // Chapter 20: Drawing Commands
373         void CmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType) const
374         { vkCmdBindIndexBuffer(handle_cast<::VkCommandBuffer>(commandBuffer), handle_cast<::VkBuffer>(buffer), offset, indexType); }
375
376         void CmdDrawIndexed(VkCommandBuffer commandBuffer, std::uint32_t indexCount, std::uint32_t instanceCount, std::uint32_t firstIndex, std::int32_t vertexOffset, std::uint32_t firstInstance) const
377         { vkCmdDrawIndexed(handle_cast<::VkCommandBuffer>(commandBuffer), indexCount, instanceCount, firstIndex, vertexOffset, firstInstance); }
378
379         // Chapter 21: Fixed-Function Vertex Processing
380         void CmdBindVertexBuffers(VkCommandBuffer commandBuffer, std::uint32_t firstBinding, std::uint32_t bindingCount, const VkBuffer *pBuffers, const VkDeviceSize *pOffsets) const
381         { vkCmdBindVertexBuffers(handle_cast<::VkCommandBuffer>(commandBuffer), firstBinding, bindingCount, handle_cast<const ::VkBuffer *>(pBuffers), pOffsets); }
382
383         // Chapter 24: Fixed-Function Vertex Post-Processing
384         void CmdSetViewport(VkCommandBuffer commandBuffer, std::uint32_t firstViewport, std::uint32_t viewportCount, const VkViewport *pViewports) const
385         { vkCmdSetViewport(handle_cast<::VkCommandBuffer>(commandBuffer), firstViewport, viewportCount, pViewports); }
386
387         // Chapter 26: Fragment Operations
388         void CmdSetScissor(VkCommandBuffer commandBuffer, std::uint32_t firstScissor, std::uint32_t scissorCount, const VkRect2D *pScissors) const
389         { vkCmdSetScissor(handle_cast<::VkCommandBuffer>(commandBuffer), firstScissor, scissorCount, pScissors); }
390
391         // Chapter 28: Dispatching Commands
392         void CmdDispatch(VkCommandBuffer commandBuffer, std::uint32_t groupCountX, std::uint32_t groupCountY, std::uint32_t groupCountZ) const
393         { vkCmdDispatch(handle_cast<::VkCommandBuffer>(commandBuffer), groupCountX, groupCountY, groupCountZ); }
394
395         // Chapter 30: Window System Integration (WSI)
396         Result GetPhysicalDeviceSurfaceCapabilities(VkSurface surface, VkSurfaceCapabilitiesKHR &rSurfaceCapabilities) const
397         { return { vkGetPhysicalDeviceSurfaceCapabilities(physicalDevice, handle_cast<::VkSurfaceKHR>(surface), &rSurfaceCapabilities), "vkGetPhysicalDeviceSurfaceCapabilities" }; }
398
399         Result GetPhysicalDeviceSurfaceFormats(VkSurface surface, std::uint32_t &rSurfaceFormatCount, VkSurfaceFormatKHR *pSurfaceFormats) const
400         { return { vkGetPhysicalDeviceSurfaceFormats(physicalDevice, handle_cast<::VkSurfaceKHR>(surface), &rSurfaceFormatCount, pSurfaceFormats), "vkGetPhysicalDeviceSurfaceFormats" }; }
401
402         Result GetPhysicalDeviceSurfacePresentModes(VkSurface surface, std::uint32_t &rPresentModeCount, VkPresentModeKHR *pPresentModes) const
403         { return { vkGetPhysicalDeviceSurfacePresentModes(physicalDevice, handle_cast<::VkSurfaceKHR>(surface), &rPresentModeCount, pPresentModes), "vkGetPhysicalDeviceSurfacePresentModes" }; }
404
405         Result CreateSwapchain(const VkSwapchainCreateInfoKHR &rCreateInfo, VkSwapchain &rSwapchain) const
406         { return { vkCreateSwapchain(device, &rCreateInfo, 0, handle_cast<::VkSwapchainKHR *>(&rSwapchain)), "vkCreateSwapchain" }; }
407
408         void DestroySwapchain(VkSwapchain swapchain) const
409         { vkDestroySwapchain(device, handle_cast<::VkSwapchainKHR>(swapchain), 0); }
410
411         void GetSwapchainImages(VkSwapchain swapchain, std::uint32_t &rSwapchainImageCount, VkImage *pSwapchainImages) const
412         { vkGetSwapchainImages(device, handle_cast<::VkSwapchainKHR>(swapchain), &rSwapchainImageCount, handle_cast<::VkImage *>(pSwapchainImages)); }
413
414         Result AcquireNextImage(VkSwapchain swapchain, std::uint64_t timeout, VkSemaphore semaphore, VkFence fence, std::uint32_t &rImageIndex) const
415         { return { vkAcquireNextImageKHR(device, handle_cast<::VkSwapchainKHR>(swapchain), timeout, handle_cast<::VkSemaphore>(semaphore), handle_cast<::VkFence>(fence), &rImageIndex), "vkAcquireNextImageKHR" }; }
416
417         Result QueuePresent(const VkPresentInfoKHR &rPresentInfo) const
418         { return { vkQueuePresent(graphicsQueue, &rPresentInfo), "vkQueuePresent" }; }
419
420         // Chapter 39: Formats
421         void GetPhysicalDeviceFormatProperties(VkFormat format, VkFormatProperties &rFormatProperties) const
422         { vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &rFormatProperties); }
423
424         // Chapter 45: Debugging
425         Result SetDebugUtilsObjectName(const VkDebugUtilsObjectNameInfoEXT &rNameInfo) const
426         { return { vkSetDebugUtilsObjectName(device, &rNameInfo), "vkSetDebugUtilsObjectName" }; }
427 };
428
429 class VulkanCommandRecorder
430 {
431 private:
432         const VulkanFunctions &vk;
433         VkCommandBuffer commandBuffer;
434
435 public:
436         VulkanCommandRecorder(const VulkanFunctions &v, VkCommandBuffer b): vk(v), commandBuffer(b) { }
437
438         void ExecuteCommands(std::uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers) const
439         { vk.CmdExecuteCommands(commandBuffer, commandBufferCount, pCommandBuffers); }
440
441         void PipelineBarrier(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) const
442         { vk.CmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers); }
443
444         void BeginRenderPass(const VkRenderPassBeginInfo &rRenderPassBegin, VkSubpassContents contents) const
445         { vk.CmdBeginRenderPass(commandBuffer, rRenderPassBegin, contents); }
446
447         void EndRenderPass() const
448         { vk.CmdEndRenderPass(commandBuffer); }
449
450         void BindPipeline(VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline) const
451         { vk.CmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline); }
452
453         void BindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, std::uint32_t firstSet, std::uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets, std::uint32_t dynamicOffsetCount, const std::uint32_t *pDynamicOffsets) const
454         { vk.CmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout, firstSet, descriptorSetCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets); }
455
456         void PushConstants(VkPipelineLayout layout, VkShaderStageFlags stageFlags, std::uint32_t offset, std::uint32_t size, const void *pValues) const
457         { vk.CmdPushConstants(commandBuffer, layout, stageFlags, offset, size, pValues); }
458
459         void CopyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, std::uint32_t regionCount, const VkBufferCopy *pRegions) const
460         { vk.CmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions); }
461
462         void CopyBufferToImage(VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, std::uint32_t regionCount, const VkBufferImageCopy *pRegions) const
463         { vk.CmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions); }
464
465         void BlitImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit *pRegions, VkFilter filter) const
466         { vk.CmdBlitImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter); }
467
468         void BindIndexBuffer(VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType) const
469         { vk.CmdBindIndexBuffer(commandBuffer, buffer, offset, indexType); }
470
471         void DrawIndexed(std::uint32_t indexCount, std::uint32_t instanceCount, std::uint32_t firstIndex, std::int32_t vertexOffset, std::uint32_t firstInstance) const
472         { vk.CmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance); }
473
474         void BindVertexBuffers(std::uint32_t firstBinding, std::uint32_t bindingCount, const VkBuffer *pBuffers, const VkDeviceSize *pOffsets) const
475         { vk.CmdBindVertexBuffers(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets); }
476
477         void SetViewport(std::uint32_t firstViewport, std::uint32_t viewportCount, const VkViewport *pViewports) const
478         { vk.CmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports); }
479
480         void SetScissor(std::uint32_t firstScissor, std::uint32_t scissorCount, const VkRect2D *pScissors) const
481         { vk.CmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors); }
482
483         void Dispatch(std::uint32_t groupCountX, std::uint32_t groupCountY, std::uint32_t groupCountZ) const
484         { vk.CmdDispatch(commandBuffer, groupCountX, groupCountY, groupCountZ); }
485 };
486
487 } // namespace GL
488 } // namespace Msp
489
490 #endif