anv/wsi: drop device from get format
[mesa.git] / src / intel / vulkan / anv_wsi.c
1 /*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include "anv_wsi.h"
25
26 VkResult
27 anv_init_wsi(struct anv_physical_device *physical_device)
28 {
29 VkResult result;
30
31 memset(physical_device->wsi_device.wsi, 0, sizeof(physical_device->wsi_device.wsi));
32
33 #ifdef VK_USE_PLATFORM_XCB_KHR
34 result = anv_x11_init_wsi(&physical_device->wsi_device, &physical_device->instance->alloc);
35 if (result != VK_SUCCESS)
36 return result;
37 #endif
38
39 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
40 result = anv_wl_init_wsi(physical_device);
41 if (result != VK_SUCCESS) {
42 #ifdef VK_USE_PLATFORM_XCB_KHR
43 anv_x11_finish_wsi(&physical_device->wsi_device, &physical_device->instance->alloc);
44 #endif
45 return result;
46 }
47 #endif
48
49 return VK_SUCCESS;
50 }
51
52 void
53 anv_finish_wsi(struct anv_physical_device *physical_device)
54 {
55 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
56 anv_wl_finish_wsi(physical_device);
57 #endif
58 #ifdef VK_USE_PLATFORM_XCB_KHR
59 anv_x11_finish_wsi(&physical_device->wsi_device, &physical_device->instance->alloc);
60 #endif
61 }
62
63 void anv_DestroySurfaceKHR(
64 VkInstance _instance,
65 VkSurfaceKHR _surface,
66 const VkAllocationCallbacks* pAllocator)
67 {
68 ANV_FROM_HANDLE(anv_instance, instance, _instance);
69 ANV_FROM_HANDLE(_VkIcdSurfaceBase, surface, _surface);
70
71 vk_free2(&instance->alloc, pAllocator, surface);
72 }
73
74 VkResult anv_GetPhysicalDeviceSurfaceSupportKHR(
75 VkPhysicalDevice physicalDevice,
76 uint32_t queueFamilyIndex,
77 VkSurfaceKHR _surface,
78 VkBool32* pSupported)
79 {
80 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
81 ANV_FROM_HANDLE(_VkIcdSurfaceBase, surface, _surface);
82 struct anv_wsi_interface *iface = device->wsi_device.wsi[surface->platform];
83
84 return iface->get_support(surface, &device->wsi_device,
85 &device->instance->alloc,
86 queueFamilyIndex, pSupported);
87 }
88
89 VkResult anv_GetPhysicalDeviceSurfaceCapabilitiesKHR(
90 VkPhysicalDevice physicalDevice,
91 VkSurfaceKHR _surface,
92 VkSurfaceCapabilitiesKHR* pSurfaceCapabilities)
93 {
94 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
95 ANV_FROM_HANDLE(_VkIcdSurfaceBase, surface, _surface);
96 struct anv_wsi_interface *iface = device->wsi_device.wsi[surface->platform];
97
98 return iface->get_capabilities(surface, pSurfaceCapabilities);
99 }
100
101 VkResult anv_GetPhysicalDeviceSurfaceFormatsKHR(
102 VkPhysicalDevice physicalDevice,
103 VkSurfaceKHR _surface,
104 uint32_t* pSurfaceFormatCount,
105 VkSurfaceFormatKHR* pSurfaceFormats)
106 {
107 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
108 ANV_FROM_HANDLE(_VkIcdSurfaceBase, surface, _surface);
109 struct anv_wsi_interface *iface = device->wsi_device.wsi[surface->platform];
110
111 return iface->get_formats(surface, &device->wsi_device, pSurfaceFormatCount,
112 pSurfaceFormats);
113 }
114
115 VkResult anv_GetPhysicalDeviceSurfacePresentModesKHR(
116 VkPhysicalDevice physicalDevice,
117 VkSurfaceKHR _surface,
118 uint32_t* pPresentModeCount,
119 VkPresentModeKHR* pPresentModes)
120 {
121 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
122 ANV_FROM_HANDLE(_VkIcdSurfaceBase, surface, _surface);
123 struct anv_wsi_interface *iface = device->wsi_device.wsi[surface->platform];
124
125 return iface->get_present_modes(surface, pPresentModeCount,
126 pPresentModes);
127 }
128
129 VkResult anv_CreateSwapchainKHR(
130 VkDevice _device,
131 const VkSwapchainCreateInfoKHR* pCreateInfo,
132 const VkAllocationCallbacks* pAllocator,
133 VkSwapchainKHR* pSwapchain)
134 {
135 ANV_FROM_HANDLE(anv_device, device, _device);
136 ANV_FROM_HANDLE(_VkIcdSurfaceBase, surface, pCreateInfo->surface);
137 struct anv_wsi_interface *iface =
138 device->instance->physicalDevice.wsi_device.wsi[surface->platform];
139 struct anv_swapchain *swapchain;
140
141 VkResult result = iface->create_swapchain(surface, device, pCreateInfo,
142 pAllocator, &swapchain);
143 if (result != VK_SUCCESS)
144 return result;
145
146 if (pAllocator)
147 swapchain->alloc = *pAllocator;
148 else
149 swapchain->alloc = device->alloc;
150
151 for (unsigned i = 0; i < ARRAY_SIZE(swapchain->fences); i++)
152 swapchain->fences[i] = VK_NULL_HANDLE;
153
154 *pSwapchain = anv_swapchain_to_handle(swapchain);
155
156 return VK_SUCCESS;
157 }
158
159 void anv_DestroySwapchainKHR(
160 VkDevice device,
161 VkSwapchainKHR _swapchain,
162 const VkAllocationCallbacks* pAllocator)
163 {
164 ANV_FROM_HANDLE(anv_swapchain, swapchain, _swapchain);
165
166 for (unsigned i = 0; i < ARRAY_SIZE(swapchain->fences); i++) {
167 if (swapchain->fences[i] != VK_NULL_HANDLE)
168 anv_DestroyFence(device, swapchain->fences[i], pAllocator);
169 }
170
171 swapchain->destroy(swapchain, pAllocator);
172 }
173
174 VkResult anv_GetSwapchainImagesKHR(
175 VkDevice device,
176 VkSwapchainKHR _swapchain,
177 uint32_t* pSwapchainImageCount,
178 VkImage* pSwapchainImages)
179 {
180 ANV_FROM_HANDLE(anv_swapchain, swapchain, _swapchain);
181
182 return swapchain->get_images(swapchain, pSwapchainImageCount,
183 pSwapchainImages);
184 }
185
186 VkResult anv_AcquireNextImageKHR(
187 VkDevice device,
188 VkSwapchainKHR _swapchain,
189 uint64_t timeout,
190 VkSemaphore semaphore,
191 VkFence fence,
192 uint32_t* pImageIndex)
193 {
194 ANV_FROM_HANDLE(anv_swapchain, swapchain, _swapchain);
195
196 return swapchain->acquire_next_image(swapchain, timeout, semaphore,
197 pImageIndex);
198 }
199
200 VkResult anv_QueuePresentKHR(
201 VkQueue _queue,
202 const VkPresentInfoKHR* pPresentInfo)
203 {
204 ANV_FROM_HANDLE(anv_queue, queue, _queue);
205 VkResult result;
206
207 for (uint32_t i = 0; i < pPresentInfo->swapchainCount; i++) {
208 ANV_FROM_HANDLE(anv_swapchain, swapchain, pPresentInfo->pSwapchains[i]);
209
210 assert(swapchain->device == queue->device);
211
212 if (swapchain->fences[0] == VK_NULL_HANDLE) {
213 result = anv_CreateFence(anv_device_to_handle(queue->device),
214 &(VkFenceCreateInfo) {
215 .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
216 .flags = 0,
217 }, &swapchain->alloc, &swapchain->fences[0]);
218 if (result != VK_SUCCESS)
219 return result;
220 } else {
221 anv_ResetFences(anv_device_to_handle(queue->device),
222 1, &swapchain->fences[0]);
223 }
224
225 anv_QueueSubmit(_queue, 0, NULL, swapchain->fences[0]);
226
227 result = swapchain->queue_present(swapchain,
228 pPresentInfo->pImageIndices[i]);
229 /* TODO: What if one of them returns OUT_OF_DATE? */
230 if (result != VK_SUCCESS)
231 return result;
232
233 VkFence last = swapchain->fences[2];
234 swapchain->fences[2] = swapchain->fences[1];
235 swapchain->fences[1] = swapchain->fences[0];
236 swapchain->fences[0] = last;
237
238 if (last != VK_NULL_HANDLE) {
239 anv_WaitForFences(anv_device_to_handle(queue->device),
240 1, &last, true, 1);
241 }
242 }
243
244 return VK_SUCCESS;
245 }