anv: add new gem/drm helpers
[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_private.h"
25 #include "wsi_common.h"
26 #include "vk_format_info.h"
27 #include "vk_util.h"
28
29 static PFN_vkVoidFunction
30 anv_wsi_proc_addr(VkPhysicalDevice physicalDevice, const char *pName)
31 {
32 ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
33 return anv_lookup_entrypoint(&physical_device->info, pName);
34 }
35
36 static void
37 anv_wsi_signal_semaphore_for_memory(VkDevice _device,
38 VkSemaphore _semaphore,
39 VkDeviceMemory _memory)
40 {
41 ANV_FROM_HANDLE(anv_device, device, _device);
42 ANV_FROM_HANDLE(anv_semaphore, semaphore, _semaphore);
43 ANV_FROM_HANDLE(anv_device_memory, memory, _memory);
44
45 /* Put a BO semaphore with the image BO in the temporary. For BO binary
46 * semaphores, we always set EXEC_OBJECT_WRITE so this creates a WaR
47 * hazard with the display engine's read to ensure that no one writes to
48 * the image before the read is complete.
49 */
50 anv_semaphore_reset_temporary(device, semaphore);
51
52 struct anv_semaphore_impl *impl = &semaphore->temporary;
53 impl->type = ANV_SEMAPHORE_TYPE_WSI_BO;
54 impl->bo = anv_bo_ref(memory->bo);
55 }
56
57 static void
58 anv_wsi_signal_fence_for_memory(VkDevice _device,
59 VkFence _fence,
60 VkDeviceMemory _memory)
61 {
62 ANV_FROM_HANDLE(anv_device, device, _device);
63 ANV_FROM_HANDLE(anv_fence, fence, _fence);
64 ANV_FROM_HANDLE(anv_device_memory, memory, _memory);
65
66 /* Put a BO fence with the image BO in the temporary. For BO fences, we
67 * always just wait until the BO isn't busy and reads from the BO should
68 * count as busy.
69 */
70 anv_fence_reset_temporary(device, fence);
71
72 struct anv_fence_impl *impl = &fence->temporary;
73 impl->type = ANV_FENCE_TYPE_WSI_BO;
74 impl->bo.bo = anv_bo_ref(memory->bo);
75 impl->bo.state = ANV_BO_FENCE_STATE_SUBMITTED;
76 }
77
78 VkResult
79 anv_init_wsi(struct anv_physical_device *physical_device)
80 {
81 VkResult result;
82
83 result = wsi_device_init(&physical_device->wsi_device,
84 anv_physical_device_to_handle(physical_device),
85 anv_wsi_proc_addr,
86 &physical_device->instance->alloc,
87 physical_device->master_fd,
88 &physical_device->instance->dri_options,
89 false);
90 if (result != VK_SUCCESS)
91 return result;
92
93 physical_device->wsi_device.supports_modifiers = true;
94 physical_device->wsi_device.signal_semaphore_for_memory =
95 anv_wsi_signal_semaphore_for_memory;
96 physical_device->wsi_device.signal_fence_for_memory =
97 anv_wsi_signal_fence_for_memory;
98
99 return VK_SUCCESS;
100 }
101
102 void
103 anv_finish_wsi(struct anv_physical_device *physical_device)
104 {
105 wsi_device_finish(&physical_device->wsi_device,
106 &physical_device->instance->alloc);
107 }
108
109 void anv_DestroySurfaceKHR(
110 VkInstance _instance,
111 VkSurfaceKHR _surface,
112 const VkAllocationCallbacks* pAllocator)
113 {
114 ANV_FROM_HANDLE(anv_instance, instance, _instance);
115 ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
116
117 if (!surface)
118 return;
119
120 vk_free2(&instance->alloc, pAllocator, surface);
121 }
122
123 VkResult anv_GetPhysicalDeviceSurfaceSupportKHR(
124 VkPhysicalDevice physicalDevice,
125 uint32_t queueFamilyIndex,
126 VkSurfaceKHR surface,
127 VkBool32* pSupported)
128 {
129 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
130
131 return wsi_common_get_surface_support(&device->wsi_device,
132 queueFamilyIndex,
133 surface,
134 pSupported);
135 }
136
137 VkResult anv_GetPhysicalDeviceSurfaceCapabilitiesKHR(
138 VkPhysicalDevice physicalDevice,
139 VkSurfaceKHR surface,
140 VkSurfaceCapabilitiesKHR* pSurfaceCapabilities)
141 {
142 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
143
144 return wsi_common_get_surface_capabilities(&device->wsi_device,
145 surface,
146 pSurfaceCapabilities);
147 }
148
149 VkResult anv_GetPhysicalDeviceSurfaceCapabilities2KHR(
150 VkPhysicalDevice physicalDevice,
151 const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
152 VkSurfaceCapabilities2KHR* pSurfaceCapabilities)
153 {
154 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
155
156 return wsi_common_get_surface_capabilities2(&device->wsi_device,
157 pSurfaceInfo,
158 pSurfaceCapabilities);
159 }
160
161 VkResult anv_GetPhysicalDeviceSurfaceCapabilities2EXT(
162 VkPhysicalDevice physicalDevice,
163 VkSurfaceKHR surface,
164 VkSurfaceCapabilities2EXT* pSurfaceCapabilities)
165 {
166 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
167
168 return wsi_common_get_surface_capabilities2ext(&device->wsi_device,
169 surface,
170 pSurfaceCapabilities);
171 }
172
173 VkResult anv_GetPhysicalDeviceSurfaceFormatsKHR(
174 VkPhysicalDevice physicalDevice,
175 VkSurfaceKHR surface,
176 uint32_t* pSurfaceFormatCount,
177 VkSurfaceFormatKHR* pSurfaceFormats)
178 {
179 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
180
181 return wsi_common_get_surface_formats(&device->wsi_device, surface,
182 pSurfaceFormatCount, pSurfaceFormats);
183 }
184
185 VkResult anv_GetPhysicalDeviceSurfaceFormats2KHR(
186 VkPhysicalDevice physicalDevice,
187 const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
188 uint32_t* pSurfaceFormatCount,
189 VkSurfaceFormat2KHR* pSurfaceFormats)
190 {
191 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
192
193 return wsi_common_get_surface_formats2(&device->wsi_device, pSurfaceInfo,
194 pSurfaceFormatCount, pSurfaceFormats);
195 }
196
197 VkResult anv_GetPhysicalDeviceSurfacePresentModesKHR(
198 VkPhysicalDevice physicalDevice,
199 VkSurfaceKHR surface,
200 uint32_t* pPresentModeCount,
201 VkPresentModeKHR* pPresentModes)
202 {
203 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
204
205 return wsi_common_get_surface_present_modes(&device->wsi_device, surface,
206 pPresentModeCount,
207 pPresentModes);
208 }
209
210 VkResult anv_CreateSwapchainKHR(
211 VkDevice _device,
212 const VkSwapchainCreateInfoKHR* pCreateInfo,
213 const VkAllocationCallbacks* pAllocator,
214 VkSwapchainKHR* pSwapchain)
215 {
216 ANV_FROM_HANDLE(anv_device, device, _device);
217 struct wsi_device *wsi_device = &device->physical->wsi_device;
218 const VkAllocationCallbacks *alloc;
219
220 if (pAllocator)
221 alloc = pAllocator;
222 else
223 alloc = &device->vk.alloc;
224
225 return wsi_common_create_swapchain(wsi_device, _device,
226 pCreateInfo, alloc, pSwapchain);
227 }
228
229 void anv_DestroySwapchainKHR(
230 VkDevice _device,
231 VkSwapchainKHR swapchain,
232 const VkAllocationCallbacks* pAllocator)
233 {
234 ANV_FROM_HANDLE(anv_device, device, _device);
235 const VkAllocationCallbacks *alloc;
236
237 if (pAllocator)
238 alloc = pAllocator;
239 else
240 alloc = &device->vk.alloc;
241
242 wsi_common_destroy_swapchain(_device, swapchain, alloc);
243 }
244
245 VkResult anv_GetSwapchainImagesKHR(
246 VkDevice device,
247 VkSwapchainKHR swapchain,
248 uint32_t* pSwapchainImageCount,
249 VkImage* pSwapchainImages)
250 {
251 return wsi_common_get_images(swapchain,
252 pSwapchainImageCount,
253 pSwapchainImages);
254 }
255
256 VkResult anv_AcquireNextImageKHR(
257 VkDevice device,
258 VkSwapchainKHR swapchain,
259 uint64_t timeout,
260 VkSemaphore semaphore,
261 VkFence fence,
262 uint32_t* pImageIndex)
263 {
264 VkAcquireNextImageInfoKHR acquire_info = {
265 .sType = VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR,
266 .swapchain = swapchain,
267 .timeout = timeout,
268 .semaphore = semaphore,
269 .fence = fence,
270 .deviceMask = 0,
271 };
272
273 return anv_AcquireNextImage2KHR(device, &acquire_info, pImageIndex);
274 }
275
276 VkResult anv_AcquireNextImage2KHR(
277 VkDevice _device,
278 const VkAcquireNextImageInfoKHR* pAcquireInfo,
279 uint32_t* pImageIndex)
280 {
281 ANV_FROM_HANDLE(anv_device, device, _device);
282
283 return wsi_common_acquire_next_image2(&device->physical->wsi_device,
284 _device, pAcquireInfo, pImageIndex);
285 }
286
287 VkResult anv_QueuePresentKHR(
288 VkQueue _queue,
289 const VkPresentInfoKHR* pPresentInfo)
290 {
291 ANV_FROM_HANDLE(anv_queue, queue, _queue);
292 struct anv_device *device = queue->device;
293
294 if (device->debug_frame_desc) {
295 device->debug_frame_desc->frame_id++;
296 if (!device->info.has_llc) {
297 gen_clflush_range(device->debug_frame_desc,
298 sizeof(*device->debug_frame_desc));
299 }
300 }
301
302 return wsi_common_queue_present(&queue->device->physical->wsi_device,
303 anv_device_to_handle(queue->device),
304 _queue, 0,
305 pPresentInfo);
306 }
307
308 VkResult anv_GetDeviceGroupPresentCapabilitiesKHR(
309 VkDevice device,
310 VkDeviceGroupPresentCapabilitiesKHR* pCapabilities)
311 {
312 memset(pCapabilities->presentMask, 0,
313 sizeof(pCapabilities->presentMask));
314 pCapabilities->presentMask[0] = 0x1;
315 pCapabilities->modes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
316
317 return VK_SUCCESS;
318 }
319
320 VkResult anv_GetDeviceGroupSurfacePresentModesKHR(
321 VkDevice device,
322 VkSurfaceKHR surface,
323 VkDeviceGroupPresentModeFlagsKHR* pModes)
324 {
325 *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
326
327 return VK_SUCCESS;
328 }
329
330 VkResult anv_GetPhysicalDevicePresentRectanglesKHR(
331 VkPhysicalDevice physicalDevice,
332 VkSurfaceKHR surface,
333 uint32_t* pRectCount,
334 VkRect2D* pRects)
335 {
336 ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
337
338 return wsi_common_get_present_rectangles(&device->wsi_device,
339 surface,
340 pRectCount, pRects);
341 }