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
32static PFN_vkVoidFunction
33radv_wsi_proc_addr(VkPhysicalDevice physicalDevice, const char *pName)
34{
35	return radv_lookup_entrypoint_unchecked(pName);
36}
37
38VkResult
39radv_init_wsi(struct radv_physical_device *physical_device)
40{
41	return wsi_device_init(&physical_device->wsi_device,
42			       radv_physical_device_to_handle(physical_device),
43			       radv_wsi_proc_addr,
44			       &physical_device->instance->alloc,
45			       physical_device->master_fd,
46			       &physical_device->instance->dri_options);
47}
48
49void
50radv_finish_wsi(struct radv_physical_device *physical_device)
51{
52	wsi_device_finish(&physical_device->wsi_device,
53			  &physical_device->instance->alloc);
54}
55
56void radv_DestroySurfaceKHR(
57	VkInstance                                   _instance,
58	VkSurfaceKHR                                 _surface,
59	const VkAllocationCallbacks*                 pAllocator)
60{
61	RADV_FROM_HANDLE(radv_instance, instance, _instance);
62	ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
63
64	vk_free2(&instance->alloc, pAllocator, surface);
65}
66
67VkResult radv_GetPhysicalDeviceSurfaceSupportKHR(
68	VkPhysicalDevice                            physicalDevice,
69	uint32_t                                    queueFamilyIndex,
70	VkSurfaceKHR                                surface,
71	VkBool32*                                   pSupported)
72{
73	RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice);
74
75	return wsi_common_get_surface_support(&device->wsi_device,
76					      queueFamilyIndex,
77					      surface,
78					      pSupported);
79}
80
81VkResult radv_GetPhysicalDeviceSurfaceCapabilitiesKHR(
82	VkPhysicalDevice                            physicalDevice,
83	VkSurfaceKHR                                surface,
84	VkSurfaceCapabilitiesKHR*                   pSurfaceCapabilities)
85{
86	RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice);
87
88	return wsi_common_get_surface_capabilities(&device->wsi_device,
89						   surface,
90						   pSurfaceCapabilities);
91}
92
93VkResult radv_GetPhysicalDeviceSurfaceCapabilities2KHR(
94	VkPhysicalDevice                            physicalDevice,
95	const VkPhysicalDeviceSurfaceInfo2KHR*      pSurfaceInfo,
96	VkSurfaceCapabilities2KHR*                  pSurfaceCapabilities)
97{
98	RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice);
99
100	return wsi_common_get_surface_capabilities2(&device->wsi_device,
101						    pSurfaceInfo,
102						    pSurfaceCapabilities);
103}
104
105VkResult radv_GetPhysicalDeviceSurfaceCapabilities2EXT(
106 	VkPhysicalDevice                            physicalDevice,
107	VkSurfaceKHR                                surface,
108	VkSurfaceCapabilities2EXT*                  pSurfaceCapabilities)
109{
110	RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice);
111
112	return wsi_common_get_surface_capabilities2ext(&device->wsi_device,
113						       surface,
114						       pSurfaceCapabilities);
115}
116
117VkResult radv_GetPhysicalDeviceSurfaceFormatsKHR(
118	VkPhysicalDevice                            physicalDevice,
119	VkSurfaceKHR                                surface,
120	uint32_t*                                   pSurfaceFormatCount,
121	VkSurfaceFormatKHR*                         pSurfaceFormats)
122{
123	RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice);
124
125	return wsi_common_get_surface_formats(&device->wsi_device,
126					      surface,
127					      pSurfaceFormatCount,
128					      pSurfaceFormats);
129}
130
131VkResult radv_GetPhysicalDeviceSurfaceFormats2KHR(
132	VkPhysicalDevice                            physicalDevice,
133	const VkPhysicalDeviceSurfaceInfo2KHR*      pSurfaceInfo,
134	uint32_t*                                   pSurfaceFormatCount,
135	VkSurfaceFormat2KHR*                        pSurfaceFormats)
136{
137	RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice);
138
139	return wsi_common_get_surface_formats2(&device->wsi_device,
140					       pSurfaceInfo,
141					       pSurfaceFormatCount,
142					       pSurfaceFormats);
143}
144
145VkResult radv_GetPhysicalDeviceSurfacePresentModesKHR(
146	VkPhysicalDevice                            physicalDevice,
147	VkSurfaceKHR                                surface,
148	uint32_t*                                   pPresentModeCount,
149	VkPresentModeKHR*                           pPresentModes)
150{
151	RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice);
152
153	return wsi_common_get_surface_present_modes(&device->wsi_device,
154						    surface,
155						    pPresentModeCount,
156						    pPresentModes);
157}
158
159VkResult radv_CreateSwapchainKHR(
160	VkDevice                                     _device,
161	const VkSwapchainCreateInfoKHR*              pCreateInfo,
162	const VkAllocationCallbacks*                 pAllocator,
163	VkSwapchainKHR*                              pSwapchain)
164{
165	RADV_FROM_HANDLE(radv_device, device, _device);
166	const VkAllocationCallbacks *alloc;
167	if (pAllocator)
168		alloc = pAllocator;
169	else
170		alloc = &device->alloc;
171
172	return wsi_common_create_swapchain(&device->physical_device->wsi_device,
173					   radv_device_to_handle(device),
174					   pCreateInfo,
175					   alloc,
176					   pSwapchain);
177}
178
179void radv_DestroySwapchainKHR(
180	VkDevice                                     _device,
181	VkSwapchainKHR                               swapchain,
182	const VkAllocationCallbacks*                 pAllocator)
183{
184	RADV_FROM_HANDLE(radv_device, device, _device);
185	const VkAllocationCallbacks *alloc;
186
187	if (pAllocator)
188		alloc = pAllocator;
189	else
190		alloc = &device->alloc;
191
192	wsi_common_destroy_swapchain(_device, swapchain, alloc);
193}
194
195VkResult radv_GetSwapchainImagesKHR(
196	VkDevice                                     device,
197	VkSwapchainKHR                               swapchain,
198	uint32_t*                                    pSwapchainImageCount,
199	VkImage*                                     pSwapchainImages)
200{
201	return wsi_common_get_images(swapchain,
202				     pSwapchainImageCount,
203				     pSwapchainImages);
204}
205
206VkResult radv_AcquireNextImageKHR(
207	VkDevice                                     device,
208	VkSwapchainKHR                               swapchain,
209	uint64_t                                     timeout,
210	VkSemaphore                                  semaphore,
211	VkFence                                      fence,
212	uint32_t*                                    pImageIndex)
213{
214	VkAcquireNextImageInfoKHR acquire_info = {
215		.sType = VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR,
216		.swapchain = swapchain,
217		.timeout = timeout,
218		.semaphore = semaphore,
219		.fence = fence,
220		.deviceMask = 0,
221	};
222
223	return radv_AcquireNextImage2KHR(device, &acquire_info, pImageIndex);
224}
225
226VkResult radv_AcquireNextImage2KHR(
227	VkDevice                                     _device,
228	const VkAcquireNextImageInfoKHR*             pAcquireInfo,
229	uint32_t*                                    pImageIndex)
230{
231	RADV_FROM_HANDLE(radv_device, device, _device);
232	struct radv_physical_device *pdevice = device->physical_device;
233	RADV_FROM_HANDLE(radv_fence, fence, pAcquireInfo->fence);
234
235	VkResult result = wsi_common_acquire_next_image2(&pdevice->wsi_device,
236							 _device,
237                                                         pAcquireInfo,
238							 pImageIndex);
239
240	if (fence && (result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR)) {
241		fence->submitted = true;
242		fence->signalled = true;
243		if (fence->temp_syncobj) {
244			device->ws->signal_syncobj(device->ws, fence->temp_syncobj);
245		} else if (fence->syncobj) {
246			device->ws->signal_syncobj(device->ws, fence->syncobj);
247		}
248	}
249	return result;
250}
251
252VkResult radv_QueuePresentKHR(
253	VkQueue                                  _queue,
254	const VkPresentInfoKHR*                  pPresentInfo)
255{
256	RADV_FROM_HANDLE(radv_queue, queue, _queue);
257	return wsi_common_queue_present(&queue->device->physical_device->wsi_device,
258					radv_device_to_handle(queue->device),
259					_queue,
260					queue->queue_family_index,
261					pPresentInfo);
262}
263
264
265VkResult radv_GetDeviceGroupPresentCapabilitiesKHR(
266    VkDevice                                    device,
267    VkDeviceGroupPresentCapabilitiesKHR*        pCapabilities)
268{
269   memset(pCapabilities->presentMask, 0,
270          sizeof(pCapabilities->presentMask));
271   pCapabilities->presentMask[0] = 0x1;
272   pCapabilities->modes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
273
274   return VK_SUCCESS;
275}
276
277VkResult radv_GetDeviceGroupSurfacePresentModesKHR(
278    VkDevice                                    device,
279    VkSurfaceKHR                                surface,
280    VkDeviceGroupPresentModeFlagsKHR*           pModes)
281{
282   *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
283
284   return VK_SUCCESS;
285}
286
287VkResult radv_GetPhysicalDevicePresentRectanglesKHR(
288	VkPhysicalDevice                            physicalDevice,
289	VkSurfaceKHR                                surface,
290	uint32_t*                                   pRectCount,
291	VkRect2D*                                   pRects)
292{
293	RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice);
294
295	return wsi_common_get_present_rectangles(&device->wsi_device,
296						 surface,
297						 pRectCount, pRects);
298}
299