1 /*
2 * Copyright © 2016 Red Hat
3 * based on intel anv code:
4 * Copyright © 2015 Intel Corporation
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 * IN THE SOFTWARE.
24 */
25
26 #include "radv_private.h"
27 #include "radv_meta.h"
28 #include "wsi_common.h"
29 #include "vk_util.h"
30 #include "util/macros.h"
31
32 static PFN_vkVoidFunction
radv_wsi_proc_addr(VkPhysicalDevice physicalDevice,const char * pName)33 radv_wsi_proc_addr(VkPhysicalDevice physicalDevice, const char *pName)
34 {
35 return radv_lookup_entrypoint(pName);
36 }
37
38 static void
radv_wsi_set_memory_ownership(VkDevice _device,VkDeviceMemory _mem,VkBool32 ownership)39 radv_wsi_set_memory_ownership(VkDevice _device,
40 VkDeviceMemory _mem,
41 VkBool32 ownership)
42 {
43 RADV_FROM_HANDLE(radv_device, device, _device);
44 RADV_FROM_HANDLE(radv_device_memory, mem, _mem);
45
46 if (ownership)
47 radv_bo_list_add(device, mem->bo);
48 else
49 radv_bo_list_remove(device, mem->bo);
50 }
51
52 VkResult
radv_init_wsi(struct radv_physical_device * physical_device)53 radv_init_wsi(struct radv_physical_device *physical_device)
54 {
55 VkResult result = wsi_device_init(&physical_device->wsi_device,
56 radv_physical_device_to_handle(physical_device),
57 radv_wsi_proc_addr,
58 &physical_device->instance->alloc,
59 physical_device->master_fd,
60 &physical_device->instance->dri_options,
61 false);
62 if (result != VK_SUCCESS)
63 return result;
64
65 physical_device->wsi_device.set_memory_ownership = radv_wsi_set_memory_ownership;
66 return VK_SUCCESS;
67 }
68
69 void
radv_finish_wsi(struct radv_physical_device * physical_device)70 radv_finish_wsi(struct radv_physical_device *physical_device)
71 {
72 wsi_device_finish(&physical_device->wsi_device,
73 &physical_device->instance->alloc);
74 }
75
radv_DestroySurfaceKHR(VkInstance _instance,VkSurfaceKHR _surface,const VkAllocationCallbacks * pAllocator)76 void radv_DestroySurfaceKHR(
77 VkInstance _instance,
78 VkSurfaceKHR _surface,
79 const VkAllocationCallbacks* pAllocator)
80 {
81 RADV_FROM_HANDLE(radv_instance, instance, _instance);
82 ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
83
84 vk_free2(&instance->alloc, pAllocator, surface);
85 }
86
radv_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,uint32_t queueFamilyIndex,VkSurfaceKHR surface,VkBool32 * pSupported)87 VkResult radv_GetPhysicalDeviceSurfaceSupportKHR(
88 VkPhysicalDevice physicalDevice,
89 uint32_t queueFamilyIndex,
90 VkSurfaceKHR surface,
91 VkBool32* pSupported)
92 {
93 RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice);
94
95 return wsi_common_get_surface_support(&device->wsi_device,
96 queueFamilyIndex,
97 surface,
98 pSupported);
99 }
100
radv_GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,VkSurfaceCapabilitiesKHR * pSurfaceCapabilities)101 VkResult radv_GetPhysicalDeviceSurfaceCapabilitiesKHR(
102 VkPhysicalDevice physicalDevice,
103 VkSurfaceKHR surface,
104 VkSurfaceCapabilitiesKHR* pSurfaceCapabilities)
105 {
106 RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice);
107
108 return wsi_common_get_surface_capabilities(&device->wsi_device,
109 surface,
110 pSurfaceCapabilities);
111 }
112
radv_GetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,VkSurfaceCapabilities2KHR * pSurfaceCapabilities)113 VkResult radv_GetPhysicalDeviceSurfaceCapabilities2KHR(
114 VkPhysicalDevice physicalDevice,
115 const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
116 VkSurfaceCapabilities2KHR* pSurfaceCapabilities)
117 {
118 RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice);
119
120 return wsi_common_get_surface_capabilities2(&device->wsi_device,
121 pSurfaceInfo,
122 pSurfaceCapabilities);
123 }
124
radv_GetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,VkSurfaceCapabilities2EXT * pSurfaceCapabilities)125 VkResult radv_GetPhysicalDeviceSurfaceCapabilities2EXT(
126 VkPhysicalDevice physicalDevice,
127 VkSurfaceKHR surface,
128 VkSurfaceCapabilities2EXT* pSurfaceCapabilities)
129 {
130 RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice);
131
132 return wsi_common_get_surface_capabilities2ext(&device->wsi_device,
133 surface,
134 pSurfaceCapabilities);
135 }
136
radv_GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,uint32_t * pSurfaceFormatCount,VkSurfaceFormatKHR * pSurfaceFormats)137 VkResult radv_GetPhysicalDeviceSurfaceFormatsKHR(
138 VkPhysicalDevice physicalDevice,
139 VkSurfaceKHR surface,
140 uint32_t* pSurfaceFormatCount,
141 VkSurfaceFormatKHR* pSurfaceFormats)
142 {
143 RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice);
144
145 return wsi_common_get_surface_formats(&device->wsi_device,
146 surface,
147 pSurfaceFormatCount,
148 pSurfaceFormats);
149 }
150
radv_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,uint32_t * pSurfaceFormatCount,VkSurfaceFormat2KHR * pSurfaceFormats)151 VkResult radv_GetPhysicalDeviceSurfaceFormats2KHR(
152 VkPhysicalDevice physicalDevice,
153 const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
154 uint32_t* pSurfaceFormatCount,
155 VkSurfaceFormat2KHR* pSurfaceFormats)
156 {
157 RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice);
158
159 return wsi_common_get_surface_formats2(&device->wsi_device,
160 pSurfaceInfo,
161 pSurfaceFormatCount,
162 pSurfaceFormats);
163 }
164
radv_GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,uint32_t * pPresentModeCount,VkPresentModeKHR * pPresentModes)165 VkResult radv_GetPhysicalDeviceSurfacePresentModesKHR(
166 VkPhysicalDevice physicalDevice,
167 VkSurfaceKHR surface,
168 uint32_t* pPresentModeCount,
169 VkPresentModeKHR* pPresentModes)
170 {
171 RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice);
172
173 return wsi_common_get_surface_present_modes(&device->wsi_device,
174 surface,
175 pPresentModeCount,
176 pPresentModes);
177 }
178
radv_CreateSwapchainKHR(VkDevice _device,const VkSwapchainCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSwapchainKHR * pSwapchain)179 VkResult radv_CreateSwapchainKHR(
180 VkDevice _device,
181 const VkSwapchainCreateInfoKHR* pCreateInfo,
182 const VkAllocationCallbacks* pAllocator,
183 VkSwapchainKHR* pSwapchain)
184 {
185 RADV_FROM_HANDLE(radv_device, device, _device);
186 const VkAllocationCallbacks *alloc;
187 if (pAllocator)
188 alloc = pAllocator;
189 else
190 alloc = &device->vk.alloc;
191
192 return wsi_common_create_swapchain(&device->physical_device->wsi_device,
193 radv_device_to_handle(device),
194 pCreateInfo,
195 alloc,
196 pSwapchain);
197 }
198
radv_DestroySwapchainKHR(VkDevice _device,VkSwapchainKHR swapchain,const VkAllocationCallbacks * pAllocator)199 void radv_DestroySwapchainKHR(
200 VkDevice _device,
201 VkSwapchainKHR swapchain,
202 const VkAllocationCallbacks* pAllocator)
203 {
204 RADV_FROM_HANDLE(radv_device, device, _device);
205 const VkAllocationCallbacks *alloc;
206
207 if (pAllocator)
208 alloc = pAllocator;
209 else
210 alloc = &device->vk.alloc;
211
212 wsi_common_destroy_swapchain(_device, swapchain, alloc);
213 }
214
radv_GetSwapchainImagesKHR(VkDevice device,VkSwapchainKHR swapchain,uint32_t * pSwapchainImageCount,VkImage * pSwapchainImages)215 VkResult radv_GetSwapchainImagesKHR(
216 VkDevice device,
217 VkSwapchainKHR swapchain,
218 uint32_t* pSwapchainImageCount,
219 VkImage* pSwapchainImages)
220 {
221 return wsi_common_get_images(swapchain,
222 pSwapchainImageCount,
223 pSwapchainImages);
224 }
225
radv_AcquireNextImageKHR(VkDevice device,VkSwapchainKHR swapchain,uint64_t timeout,VkSemaphore semaphore,VkFence fence,uint32_t * pImageIndex)226 VkResult radv_AcquireNextImageKHR(
227 VkDevice device,
228 VkSwapchainKHR swapchain,
229 uint64_t timeout,
230 VkSemaphore semaphore,
231 VkFence fence,
232 uint32_t* pImageIndex)
233 {
234 VkAcquireNextImageInfoKHR acquire_info = {
235 .sType = VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR,
236 .swapchain = swapchain,
237 .timeout = timeout,
238 .semaphore = semaphore,
239 .fence = fence,
240 .deviceMask = 0,
241 };
242
243 return radv_AcquireNextImage2KHR(device, &acquire_info, pImageIndex);
244 }
245
radv_AcquireNextImage2KHR(VkDevice _device,const VkAcquireNextImageInfoKHR * pAcquireInfo,uint32_t * pImageIndex)246 VkResult radv_AcquireNextImage2KHR(
247 VkDevice _device,
248 const VkAcquireNextImageInfoKHR* pAcquireInfo,
249 uint32_t* pImageIndex)
250 {
251 RADV_FROM_HANDLE(radv_device, device, _device);
252 struct radv_physical_device *pdevice = device->physical_device;
253 RADV_FROM_HANDLE(radv_fence, fence, pAcquireInfo->fence);
254 RADV_FROM_HANDLE(radv_semaphore, semaphore, pAcquireInfo->semaphore);
255
256 VkResult result = wsi_common_acquire_next_image2(&pdevice->wsi_device,
257 _device,
258 pAcquireInfo,
259 pImageIndex);
260
261 if (result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR) {
262 if (fence) {
263 struct radv_fence_part *part =
264 fence->temporary.kind != RADV_FENCE_NONE ?
265 &fence->temporary : &fence->permanent;
266
267 switch (part->kind) {
268 case RADV_FENCE_NONE:
269 break;
270 case RADV_FENCE_WINSYS:
271 device->ws->signal_fence(part->fence);
272 break;
273 case RADV_FENCE_SYNCOBJ:
274 device->ws->signal_syncobj(device->ws, part->syncobj, 0);
275 break;
276 default:
277 unreachable("Invalid WSI fence type");
278 }
279 }
280 if (semaphore) {
281 struct radv_semaphore_part *part =
282 semaphore->temporary.kind != RADV_SEMAPHORE_NONE ?
283 &semaphore->temporary : &semaphore->permanent;
284
285 switch (part->kind) {
286 case RADV_SEMAPHORE_NONE:
287 case RADV_SEMAPHORE_WINSYS:
288 /* Do not need to do anything. */
289 break;
290 case RADV_SEMAPHORE_TIMELINE:
291 case RADV_SEMAPHORE_TIMELINE_SYNCOBJ:
292 unreachable("WSI only allows binary semaphores.");
293 case RADV_SEMAPHORE_SYNCOBJ:
294 device->ws->signal_syncobj(device->ws, part->syncobj, 0);
295 break;
296 }
297 }
298 }
299 return result;
300 }
301
radv_QueuePresentKHR(VkQueue _queue,const VkPresentInfoKHR * pPresentInfo)302 VkResult radv_QueuePresentKHR(
303 VkQueue _queue,
304 const VkPresentInfoKHR* pPresentInfo)
305 {
306 RADV_FROM_HANDLE(radv_queue, queue, _queue);
307 return wsi_common_queue_present(&queue->device->physical_device->wsi_device,
308 radv_device_to_handle(queue->device),
309 _queue,
310 queue->queue_family_index,
311 pPresentInfo);
312 }
313
314
radv_GetDeviceGroupPresentCapabilitiesKHR(VkDevice device,VkDeviceGroupPresentCapabilitiesKHR * pCapabilities)315 VkResult radv_GetDeviceGroupPresentCapabilitiesKHR(
316 VkDevice device,
317 VkDeviceGroupPresentCapabilitiesKHR* pCapabilities)
318 {
319 memset(pCapabilities->presentMask, 0,
320 sizeof(pCapabilities->presentMask));
321 pCapabilities->presentMask[0] = 0x1;
322 pCapabilities->modes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
323
324 return VK_SUCCESS;
325 }
326
radv_GetDeviceGroupSurfacePresentModesKHR(VkDevice device,VkSurfaceKHR surface,VkDeviceGroupPresentModeFlagsKHR * pModes)327 VkResult radv_GetDeviceGroupSurfacePresentModesKHR(
328 VkDevice device,
329 VkSurfaceKHR surface,
330 VkDeviceGroupPresentModeFlagsKHR* pModes)
331 {
332 *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
333
334 return VK_SUCCESS;
335 }
336
radv_GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,uint32_t * pRectCount,VkRect2D * pRects)337 VkResult radv_GetPhysicalDevicePresentRectanglesKHR(
338 VkPhysicalDevice physicalDevice,
339 VkSurfaceKHR surface,
340 uint32_t* pRectCount,
341 VkRect2D* pRects)
342 {
343 RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice);
344
345 return wsi_common_get_present_rectangles(&device->wsi_device,
346 surface,
347 pRectCount, pRects);
348 }
349