xref: /aosp_15_r20/external/mesa3d/src/vulkan/wsi/wsi_common.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2017 Intel Corporation
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker  *
11*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker  * Software.
14*61046927SAndroid Build Coastguard Worker  *
15*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker  */
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker #include "wsi_common_private.h"
25*61046927SAndroid Build Coastguard Worker #include "wsi_common_entrypoints.h"
26*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
27*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
28*61046927SAndroid Build Coastguard Worker #include "util/os_file.h"
29*61046927SAndroid Build Coastguard Worker #include "util/os_time.h"
30*61046927SAndroid Build Coastguard Worker #include "util/xmlconfig.h"
31*61046927SAndroid Build Coastguard Worker #include "vk_device.h"
32*61046927SAndroid Build Coastguard Worker #include "vk_fence.h"
33*61046927SAndroid Build Coastguard Worker #include "vk_format.h"
34*61046927SAndroid Build Coastguard Worker #include "vk_instance.h"
35*61046927SAndroid Build Coastguard Worker #include "vk_physical_device.h"
36*61046927SAndroid Build Coastguard Worker #include "vk_queue.h"
37*61046927SAndroid Build Coastguard Worker #include "vk_semaphore.h"
38*61046927SAndroid Build Coastguard Worker #include "vk_sync.h"
39*61046927SAndroid Build Coastguard Worker #include "vk_sync_dummy.h"
40*61046927SAndroid Build Coastguard Worker #include "vk_util.h"
41*61046927SAndroid Build Coastguard Worker 
42*61046927SAndroid Build Coastguard Worker #include <time.h>
43*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
44*61046927SAndroid Build Coastguard Worker #include <stdio.h>
45*61046927SAndroid Build Coastguard Worker 
46*61046927SAndroid Build Coastguard Worker #ifndef _WIN32
47*61046927SAndroid Build Coastguard Worker #include <unistd.h>
48*61046927SAndroid Build Coastguard Worker #endif
49*61046927SAndroid Build Coastguard Worker 
50*61046927SAndroid Build Coastguard Worker uint64_t WSI_DEBUG;
51*61046927SAndroid Build Coastguard Worker 
52*61046927SAndroid Build Coastguard Worker static const struct debug_control debug_control[] = {
53*61046927SAndroid Build Coastguard Worker    { "buffer",       WSI_DEBUG_BUFFER },
54*61046927SAndroid Build Coastguard Worker    { "sw",           WSI_DEBUG_SW },
55*61046927SAndroid Build Coastguard Worker    { "noshm",        WSI_DEBUG_NOSHM },
56*61046927SAndroid Build Coastguard Worker    { "linear",       WSI_DEBUG_LINEAR },
57*61046927SAndroid Build Coastguard Worker    { "dxgi",         WSI_DEBUG_DXGI },
58*61046927SAndroid Build Coastguard Worker    { NULL, },
59*61046927SAndroid Build Coastguard Worker };
60*61046927SAndroid Build Coastguard Worker 
present_false(VkPhysicalDevice pdevice,int fd)61*61046927SAndroid Build Coastguard Worker static bool present_false(VkPhysicalDevice pdevice, int fd) {
62*61046927SAndroid Build Coastguard Worker    return false;
63*61046927SAndroid Build Coastguard Worker }
64*61046927SAndroid Build Coastguard Worker 
65*61046927SAndroid Build Coastguard Worker VkResult
wsi_device_init(struct wsi_device * wsi,VkPhysicalDevice pdevice,WSI_FN_GetPhysicalDeviceProcAddr proc_addr,const VkAllocationCallbacks * alloc,int display_fd,const struct driOptionCache * dri_options,const struct wsi_device_options * device_options)66*61046927SAndroid Build Coastguard Worker wsi_device_init(struct wsi_device *wsi,
67*61046927SAndroid Build Coastguard Worker                 VkPhysicalDevice pdevice,
68*61046927SAndroid Build Coastguard Worker                 WSI_FN_GetPhysicalDeviceProcAddr proc_addr,
69*61046927SAndroid Build Coastguard Worker                 const VkAllocationCallbacks *alloc,
70*61046927SAndroid Build Coastguard Worker                 int display_fd,
71*61046927SAndroid Build Coastguard Worker                 const struct driOptionCache *dri_options,
72*61046927SAndroid Build Coastguard Worker                 const struct wsi_device_options *device_options)
73*61046927SAndroid Build Coastguard Worker {
74*61046927SAndroid Build Coastguard Worker    const char *present_mode;
75*61046927SAndroid Build Coastguard Worker    UNUSED VkResult result;
76*61046927SAndroid Build Coastguard Worker 
77*61046927SAndroid Build Coastguard Worker    WSI_DEBUG = parse_debug_string(getenv("MESA_VK_WSI_DEBUG"), debug_control);
78*61046927SAndroid Build Coastguard Worker 
79*61046927SAndroid Build Coastguard Worker    util_cpu_trace_init();
80*61046927SAndroid Build Coastguard Worker 
81*61046927SAndroid Build Coastguard Worker    memset(wsi, 0, sizeof(*wsi));
82*61046927SAndroid Build Coastguard Worker 
83*61046927SAndroid Build Coastguard Worker    wsi->instance_alloc = *alloc;
84*61046927SAndroid Build Coastguard Worker    wsi->pdevice = pdevice;
85*61046927SAndroid Build Coastguard Worker    wsi->supports_scanout = true;
86*61046927SAndroid Build Coastguard Worker    wsi->sw = device_options->sw_device || (WSI_DEBUG & WSI_DEBUG_SW);
87*61046927SAndroid Build Coastguard Worker    wsi->wants_linear = (WSI_DEBUG & WSI_DEBUG_LINEAR) != 0;
88*61046927SAndroid Build Coastguard Worker    wsi->x11.extra_xwayland_image = device_options->extra_xwayland_image;
89*61046927SAndroid Build Coastguard Worker #define WSI_GET_CB(func) \
90*61046927SAndroid Build Coastguard Worker    PFN_vk##func func = (PFN_vk##func)proc_addr(pdevice, "vk" #func)
91*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(GetPhysicalDeviceExternalSemaphoreProperties);
92*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(GetPhysicalDeviceProperties2);
93*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(GetPhysicalDeviceMemoryProperties);
94*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(GetPhysicalDeviceQueueFamilyProperties);
95*61046927SAndroid Build Coastguard Worker #undef WSI_GET_CB
96*61046927SAndroid Build Coastguard Worker 
97*61046927SAndroid Build Coastguard Worker    wsi->drm_info.sType =
98*61046927SAndroid Build Coastguard Worker       VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT;
99*61046927SAndroid Build Coastguard Worker    wsi->pci_bus_info.sType =
100*61046927SAndroid Build Coastguard Worker       VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT;
101*61046927SAndroid Build Coastguard Worker    wsi->pci_bus_info.pNext = &wsi->drm_info;
102*61046927SAndroid Build Coastguard Worker    VkPhysicalDeviceProperties2 pdp2 = {
103*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
104*61046927SAndroid Build Coastguard Worker       .pNext = &wsi->pci_bus_info,
105*61046927SAndroid Build Coastguard Worker    };
106*61046927SAndroid Build Coastguard Worker    GetPhysicalDeviceProperties2(pdevice, &pdp2);
107*61046927SAndroid Build Coastguard Worker 
108*61046927SAndroid Build Coastguard Worker    wsi->maxImageDimension2D = pdp2.properties.limits.maxImageDimension2D;
109*61046927SAndroid Build Coastguard Worker    assert(pdp2.properties.limits.optimalBufferCopyRowPitchAlignment <= UINT32_MAX);
110*61046927SAndroid Build Coastguard Worker    wsi->optimalBufferCopyRowPitchAlignment =
111*61046927SAndroid Build Coastguard Worker       pdp2.properties.limits.optimalBufferCopyRowPitchAlignment;
112*61046927SAndroid Build Coastguard Worker    wsi->override_present_mode = VK_PRESENT_MODE_MAX_ENUM_KHR;
113*61046927SAndroid Build Coastguard Worker 
114*61046927SAndroid Build Coastguard Worker    GetPhysicalDeviceMemoryProperties(pdevice, &wsi->memory_props);
115*61046927SAndroid Build Coastguard Worker    GetPhysicalDeviceQueueFamilyProperties(pdevice, &wsi->queue_family_count, NULL);
116*61046927SAndroid Build Coastguard Worker 
117*61046927SAndroid Build Coastguard Worker    assert(wsi->queue_family_count <= 64);
118*61046927SAndroid Build Coastguard Worker    VkQueueFamilyProperties queue_properties[64];
119*61046927SAndroid Build Coastguard Worker    GetPhysicalDeviceQueueFamilyProperties(pdevice, &wsi->queue_family_count, queue_properties);
120*61046927SAndroid Build Coastguard Worker 
121*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < wsi->queue_family_count; i++) {
122*61046927SAndroid Build Coastguard Worker       VkFlags req_flags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT;
123*61046927SAndroid Build Coastguard Worker       if (queue_properties[i].queueFlags & req_flags)
124*61046927SAndroid Build Coastguard Worker          wsi->queue_supports_blit |= BITFIELD64_BIT(i);
125*61046927SAndroid Build Coastguard Worker    }
126*61046927SAndroid Build Coastguard Worker 
127*61046927SAndroid Build Coastguard Worker    for (VkExternalSemaphoreHandleTypeFlags handle_type = 1;
128*61046927SAndroid Build Coastguard Worker         handle_type <= VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
129*61046927SAndroid Build Coastguard Worker         handle_type <<= 1) {
130*61046927SAndroid Build Coastguard Worker       VkPhysicalDeviceExternalSemaphoreInfo esi = {
131*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
132*61046927SAndroid Build Coastguard Worker          .handleType = handle_type,
133*61046927SAndroid Build Coastguard Worker       };
134*61046927SAndroid Build Coastguard Worker       VkExternalSemaphoreProperties esp = {
135*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES,
136*61046927SAndroid Build Coastguard Worker       };
137*61046927SAndroid Build Coastguard Worker       GetPhysicalDeviceExternalSemaphoreProperties(pdevice, &esi, &esp);
138*61046927SAndroid Build Coastguard Worker 
139*61046927SAndroid Build Coastguard Worker       if (esp.externalSemaphoreFeatures &
140*61046927SAndroid Build Coastguard Worker           VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT)
141*61046927SAndroid Build Coastguard Worker          wsi->semaphore_export_handle_types |= handle_type;
142*61046927SAndroid Build Coastguard Worker 
143*61046927SAndroid Build Coastguard Worker       VkSemaphoreTypeCreateInfo timeline_tci = {
144*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
145*61046927SAndroid Build Coastguard Worker          .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE_KHR,
146*61046927SAndroid Build Coastguard Worker       };
147*61046927SAndroid Build Coastguard Worker       esi.pNext = &timeline_tci;
148*61046927SAndroid Build Coastguard Worker       GetPhysicalDeviceExternalSemaphoreProperties(pdevice, &esi, &esp);
149*61046927SAndroid Build Coastguard Worker 
150*61046927SAndroid Build Coastguard Worker       if (esp.externalSemaphoreFeatures &
151*61046927SAndroid Build Coastguard Worker           VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT)
152*61046927SAndroid Build Coastguard Worker          wsi->timeline_semaphore_export_handle_types |= handle_type;
153*61046927SAndroid Build Coastguard Worker    }
154*61046927SAndroid Build Coastguard Worker 
155*61046927SAndroid Build Coastguard Worker    const struct vk_device_extension_table *supported_extensions =
156*61046927SAndroid Build Coastguard Worker       &vk_physical_device_from_handle(pdevice)->supported_extensions;
157*61046927SAndroid Build Coastguard Worker    wsi->has_import_memory_host =
158*61046927SAndroid Build Coastguard Worker       supported_extensions->EXT_external_memory_host;
159*61046927SAndroid Build Coastguard Worker    wsi->khr_present_wait =
160*61046927SAndroid Build Coastguard Worker       supported_extensions->KHR_present_id &&
161*61046927SAndroid Build Coastguard Worker       supported_extensions->KHR_present_wait;
162*61046927SAndroid Build Coastguard Worker    wsi->has_timeline_semaphore =
163*61046927SAndroid Build Coastguard Worker       supported_extensions->KHR_timeline_semaphore;
164*61046927SAndroid Build Coastguard Worker 
165*61046927SAndroid Build Coastguard Worker    /* We cannot expose KHR_present_wait without timeline semaphores. */
166*61046927SAndroid Build Coastguard Worker    assert(!wsi->khr_present_wait || supported_extensions->KHR_timeline_semaphore);
167*61046927SAndroid Build Coastguard Worker 
168*61046927SAndroid Build Coastguard Worker    list_inithead(&wsi->hotplug_fences);
169*61046927SAndroid Build Coastguard Worker 
170*61046927SAndroid Build Coastguard Worker #define WSI_GET_CB(func) \
171*61046927SAndroid Build Coastguard Worker    wsi->func = (PFN_vk##func)proc_addr(pdevice, "vk" #func)
172*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(AllocateMemory);
173*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(AllocateCommandBuffers);
174*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(BindBufferMemory);
175*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(BindImageMemory);
176*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(BeginCommandBuffer);
177*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(CmdPipelineBarrier);
178*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(CmdCopyImage);
179*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(CmdCopyImageToBuffer);
180*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(CreateBuffer);
181*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(CreateCommandPool);
182*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(CreateFence);
183*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(CreateImage);
184*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(CreateSemaphore);
185*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(DestroyBuffer);
186*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(DestroyCommandPool);
187*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(DestroyFence);
188*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(DestroyImage);
189*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(DestroySemaphore);
190*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(EndCommandBuffer);
191*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(FreeMemory);
192*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(FreeCommandBuffers);
193*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(GetBufferMemoryRequirements);
194*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(GetFenceStatus);
195*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(GetImageDrmFormatModifierPropertiesEXT);
196*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(GetImageMemoryRequirements);
197*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(GetImageSubresourceLayout);
198*61046927SAndroid Build Coastguard Worker    if (!wsi->sw)
199*61046927SAndroid Build Coastguard Worker       WSI_GET_CB(GetMemoryFdKHR);
200*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(GetPhysicalDeviceFormatProperties);
201*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(GetPhysicalDeviceFormatProperties2);
202*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(GetPhysicalDeviceImageFormatProperties2);
203*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(GetSemaphoreFdKHR);
204*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(ResetFences);
205*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(QueueSubmit);
206*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(WaitForFences);
207*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(MapMemory);
208*61046927SAndroid Build Coastguard Worker    WSI_GET_CB(UnmapMemory);
209*61046927SAndroid Build Coastguard Worker    if (wsi->khr_present_wait)
210*61046927SAndroid Build Coastguard Worker       WSI_GET_CB(WaitSemaphores);
211*61046927SAndroid Build Coastguard Worker #undef WSI_GET_CB
212*61046927SAndroid Build Coastguard Worker 
213*61046927SAndroid Build Coastguard Worker #if defined(VK_USE_PLATFORM_XCB_KHR)
214*61046927SAndroid Build Coastguard Worker    result = wsi_x11_init_wsi(wsi, alloc, dri_options);
215*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
216*61046927SAndroid Build Coastguard Worker       goto fail;
217*61046927SAndroid Build Coastguard Worker #endif
218*61046927SAndroid Build Coastguard Worker 
219*61046927SAndroid Build Coastguard Worker #ifdef VK_USE_PLATFORM_WAYLAND_KHR
220*61046927SAndroid Build Coastguard Worker    result = wsi_wl_init_wsi(wsi, alloc, pdevice);
221*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
222*61046927SAndroid Build Coastguard Worker       goto fail;
223*61046927SAndroid Build Coastguard Worker #endif
224*61046927SAndroid Build Coastguard Worker 
225*61046927SAndroid Build Coastguard Worker #ifdef VK_USE_PLATFORM_WIN32_KHR
226*61046927SAndroid Build Coastguard Worker    result = wsi_win32_init_wsi(wsi, alloc, pdevice);
227*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
228*61046927SAndroid Build Coastguard Worker       goto fail;
229*61046927SAndroid Build Coastguard Worker #endif
230*61046927SAndroid Build Coastguard Worker 
231*61046927SAndroid Build Coastguard Worker #ifdef VK_USE_PLATFORM_DISPLAY_KHR
232*61046927SAndroid Build Coastguard Worker    result = wsi_display_init_wsi(wsi, alloc, display_fd);
233*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
234*61046927SAndroid Build Coastguard Worker       goto fail;
235*61046927SAndroid Build Coastguard Worker #endif
236*61046927SAndroid Build Coastguard Worker 
237*61046927SAndroid Build Coastguard Worker #ifdef VK_USE_PLATFORM_METAL_EXT
238*61046927SAndroid Build Coastguard Worker    result = wsi_metal_init_wsi(wsi, alloc, pdevice);
239*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
240*61046927SAndroid Build Coastguard Worker       goto fail;
241*61046927SAndroid Build Coastguard Worker #endif
242*61046927SAndroid Build Coastguard Worker 
243*61046927SAndroid Build Coastguard Worker #ifndef VK_USE_PLATFORM_WIN32_KHR
244*61046927SAndroid Build Coastguard Worker    result = wsi_headless_init_wsi(wsi, alloc, pdevice);
245*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
246*61046927SAndroid Build Coastguard Worker       goto fail;
247*61046927SAndroid Build Coastguard Worker #endif
248*61046927SAndroid Build Coastguard Worker 
249*61046927SAndroid Build Coastguard Worker    present_mode = getenv("MESA_VK_WSI_PRESENT_MODE");
250*61046927SAndroid Build Coastguard Worker    if (present_mode) {
251*61046927SAndroid Build Coastguard Worker       if (!strcmp(present_mode, "fifo")) {
252*61046927SAndroid Build Coastguard Worker          wsi->override_present_mode = VK_PRESENT_MODE_FIFO_KHR;
253*61046927SAndroid Build Coastguard Worker       } else if (!strcmp(present_mode, "relaxed")) {
254*61046927SAndroid Build Coastguard Worker           wsi->override_present_mode = VK_PRESENT_MODE_FIFO_RELAXED_KHR;
255*61046927SAndroid Build Coastguard Worker       } else if (!strcmp(present_mode, "mailbox")) {
256*61046927SAndroid Build Coastguard Worker          wsi->override_present_mode = VK_PRESENT_MODE_MAILBOX_KHR;
257*61046927SAndroid Build Coastguard Worker       } else if (!strcmp(present_mode, "immediate")) {
258*61046927SAndroid Build Coastguard Worker          wsi->override_present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR;
259*61046927SAndroid Build Coastguard Worker       } else {
260*61046927SAndroid Build Coastguard Worker          fprintf(stderr, "Invalid MESA_VK_WSI_PRESENT_MODE value!\n");
261*61046927SAndroid Build Coastguard Worker       }
262*61046927SAndroid Build Coastguard Worker    }
263*61046927SAndroid Build Coastguard Worker 
264*61046927SAndroid Build Coastguard Worker    wsi->force_headless_swapchain =
265*61046927SAndroid Build Coastguard Worker       debug_get_bool_option("MESA_VK_WSI_HEADLESS_SWAPCHAIN", false);
266*61046927SAndroid Build Coastguard Worker 
267*61046927SAndroid Build Coastguard Worker    if (dri_options) {
268*61046927SAndroid Build Coastguard Worker       if (driCheckOption(dri_options, "adaptive_sync", DRI_BOOL))
269*61046927SAndroid Build Coastguard Worker          wsi->enable_adaptive_sync = driQueryOptionb(dri_options,
270*61046927SAndroid Build Coastguard Worker                                                      "adaptive_sync");
271*61046927SAndroid Build Coastguard Worker 
272*61046927SAndroid Build Coastguard Worker       if (driCheckOption(dri_options, "vk_wsi_force_bgra8_unorm_first",  DRI_BOOL)) {
273*61046927SAndroid Build Coastguard Worker          wsi->force_bgra8_unorm_first =
274*61046927SAndroid Build Coastguard Worker             driQueryOptionb(dri_options, "vk_wsi_force_bgra8_unorm_first");
275*61046927SAndroid Build Coastguard Worker       }
276*61046927SAndroid Build Coastguard Worker 
277*61046927SAndroid Build Coastguard Worker       if (driCheckOption(dri_options, "vk_wsi_force_swapchain_to_current_extent",  DRI_BOOL)) {
278*61046927SAndroid Build Coastguard Worker          wsi->force_swapchain_to_currentExtent =
279*61046927SAndroid Build Coastguard Worker             driQueryOptionb(dri_options, "vk_wsi_force_swapchain_to_current_extent");
280*61046927SAndroid Build Coastguard Worker       }
281*61046927SAndroid Build Coastguard Worker    }
282*61046927SAndroid Build Coastguard Worker 
283*61046927SAndroid Build Coastguard Worker    /* can_present_on_device is a function pointer used to determine if images
284*61046927SAndroid Build Coastguard Worker     * can be presented directly on a given device file descriptor (fd).
285*61046927SAndroid Build Coastguard Worker     * If HAVE_LIBDRM is defined, it will be initialized to a platform-specific
286*61046927SAndroid Build Coastguard Worker     * function (wsi_device_matches_drm_fd). Otherwise, it is initialized to
287*61046927SAndroid Build Coastguard Worker     * present_false to ensure that it always returns false, preventing potential
288*61046927SAndroid Build Coastguard Worker     * segmentation faults from unchecked calls.
289*61046927SAndroid Build Coastguard Worker     * Drivers for non-PCI based GPUs are expected to override this after calling
290*61046927SAndroid Build Coastguard Worker     * wsi_device_init().
291*61046927SAndroid Build Coastguard Worker     */
292*61046927SAndroid Build Coastguard Worker #ifdef HAVE_LIBDRM
293*61046927SAndroid Build Coastguard Worker    wsi->can_present_on_device = wsi_device_matches_drm_fd;
294*61046927SAndroid Build Coastguard Worker #else
295*61046927SAndroid Build Coastguard Worker    wsi->can_present_on_device = present_false;
296*61046927SAndroid Build Coastguard Worker #endif
297*61046927SAndroid Build Coastguard Worker 
298*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
299*61046927SAndroid Build Coastguard Worker fail:
300*61046927SAndroid Build Coastguard Worker    wsi_device_finish(wsi, alloc);
301*61046927SAndroid Build Coastguard Worker    return result;
302*61046927SAndroid Build Coastguard Worker }
303*61046927SAndroid Build Coastguard Worker 
304*61046927SAndroid Build Coastguard Worker void
wsi_device_finish(struct wsi_device * wsi,const VkAllocationCallbacks * alloc)305*61046927SAndroid Build Coastguard Worker wsi_device_finish(struct wsi_device *wsi,
306*61046927SAndroid Build Coastguard Worker                   const VkAllocationCallbacks *alloc)
307*61046927SAndroid Build Coastguard Worker {
308*61046927SAndroid Build Coastguard Worker #ifndef VK_USE_PLATFORM_WIN32_KHR
309*61046927SAndroid Build Coastguard Worker    wsi_headless_finish_wsi(wsi, alloc);
310*61046927SAndroid Build Coastguard Worker #endif
311*61046927SAndroid Build Coastguard Worker #ifdef VK_USE_PLATFORM_DISPLAY_KHR
312*61046927SAndroid Build Coastguard Worker    wsi_display_finish_wsi(wsi, alloc);
313*61046927SAndroid Build Coastguard Worker #endif
314*61046927SAndroid Build Coastguard Worker #ifdef VK_USE_PLATFORM_WAYLAND_KHR
315*61046927SAndroid Build Coastguard Worker    wsi_wl_finish_wsi(wsi, alloc);
316*61046927SAndroid Build Coastguard Worker #endif
317*61046927SAndroid Build Coastguard Worker #ifdef VK_USE_PLATFORM_WIN32_KHR
318*61046927SAndroid Build Coastguard Worker    wsi_win32_finish_wsi(wsi, alloc);
319*61046927SAndroid Build Coastguard Worker #endif
320*61046927SAndroid Build Coastguard Worker #if defined(VK_USE_PLATFORM_XCB_KHR)
321*61046927SAndroid Build Coastguard Worker    wsi_x11_finish_wsi(wsi, alloc);
322*61046927SAndroid Build Coastguard Worker #endif
323*61046927SAndroid Build Coastguard Worker #if defined(VK_USE_PLATFORM_METAL_EXT)
324*61046927SAndroid Build Coastguard Worker    wsi_metal_finish_wsi(wsi, alloc);
325*61046927SAndroid Build Coastguard Worker #endif
326*61046927SAndroid Build Coastguard Worker }
327*61046927SAndroid Build Coastguard Worker 
328*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
wsi_DestroySurfaceKHR(VkInstance _instance,VkSurfaceKHR _surface,const VkAllocationCallbacks * pAllocator)329*61046927SAndroid Build Coastguard Worker wsi_DestroySurfaceKHR(VkInstance _instance,
330*61046927SAndroid Build Coastguard Worker                       VkSurfaceKHR _surface,
331*61046927SAndroid Build Coastguard Worker                       const VkAllocationCallbacks *pAllocator)
332*61046927SAndroid Build Coastguard Worker {
333*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_instance, instance, _instance);
334*61046927SAndroid Build Coastguard Worker    ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
335*61046927SAndroid Build Coastguard Worker 
336*61046927SAndroid Build Coastguard Worker    if (!surface)
337*61046927SAndroid Build Coastguard Worker       return;
338*61046927SAndroid Build Coastguard Worker 
339*61046927SAndroid Build Coastguard Worker #ifdef VK_USE_PLATFORM_WAYLAND_KHR
340*61046927SAndroid Build Coastguard Worker    if (surface->platform == VK_ICD_WSI_PLATFORM_WAYLAND) {
341*61046927SAndroid Build Coastguard Worker       wsi_wl_surface_destroy(surface, _instance, pAllocator);
342*61046927SAndroid Build Coastguard Worker       return;
343*61046927SAndroid Build Coastguard Worker    }
344*61046927SAndroid Build Coastguard Worker #endif
345*61046927SAndroid Build Coastguard Worker #ifdef VK_USE_PLATFORM_WIN32_KHR
346*61046927SAndroid Build Coastguard Worker    if (surface->platform == VK_ICD_WSI_PLATFORM_WIN32) {
347*61046927SAndroid Build Coastguard Worker       wsi_win32_surface_destroy(surface, _instance, pAllocator);
348*61046927SAndroid Build Coastguard Worker       return;
349*61046927SAndroid Build Coastguard Worker    }
350*61046927SAndroid Build Coastguard Worker #endif
351*61046927SAndroid Build Coastguard Worker 
352*61046927SAndroid Build Coastguard Worker    vk_free2(&instance->alloc, pAllocator, surface);
353*61046927SAndroid Build Coastguard Worker }
354*61046927SAndroid Build Coastguard Worker 
355*61046927SAndroid Build Coastguard Worker void
wsi_device_setup_syncobj_fd(struct wsi_device * wsi_device,int fd)356*61046927SAndroid Build Coastguard Worker wsi_device_setup_syncobj_fd(struct wsi_device *wsi_device,
357*61046927SAndroid Build Coastguard Worker                             int fd)
358*61046927SAndroid Build Coastguard Worker {
359*61046927SAndroid Build Coastguard Worker #ifdef VK_USE_PLATFORM_DISPLAY_KHR
360*61046927SAndroid Build Coastguard Worker    wsi_display_setup_syncobj_fd(wsi_device, fd);
361*61046927SAndroid Build Coastguard Worker #endif
362*61046927SAndroid Build Coastguard Worker }
363*61046927SAndroid Build Coastguard Worker 
364*61046927SAndroid Build Coastguard Worker static enum wsi_swapchain_blit_type
get_blit_type(const struct wsi_device * wsi,const struct wsi_base_image_params * params,VkDevice device)365*61046927SAndroid Build Coastguard Worker get_blit_type(const struct wsi_device *wsi,
366*61046927SAndroid Build Coastguard Worker               const struct wsi_base_image_params *params,
367*61046927SAndroid Build Coastguard Worker               VkDevice device)
368*61046927SAndroid Build Coastguard Worker {
369*61046927SAndroid Build Coastguard Worker    switch (params->image_type) {
370*61046927SAndroid Build Coastguard Worker    case WSI_IMAGE_TYPE_CPU: {
371*61046927SAndroid Build Coastguard Worker       const struct wsi_cpu_image_params *cpu_params =
372*61046927SAndroid Build Coastguard Worker          container_of(params, const struct wsi_cpu_image_params, base);
373*61046927SAndroid Build Coastguard Worker       return wsi_cpu_image_needs_buffer_blit(wsi, cpu_params) ?
374*61046927SAndroid Build Coastguard Worker          WSI_SWAPCHAIN_BUFFER_BLIT : WSI_SWAPCHAIN_NO_BLIT;
375*61046927SAndroid Build Coastguard Worker    }
376*61046927SAndroid Build Coastguard Worker #ifdef HAVE_LIBDRM
377*61046927SAndroid Build Coastguard Worker    case WSI_IMAGE_TYPE_DRM: {
378*61046927SAndroid Build Coastguard Worker       const struct wsi_drm_image_params *drm_params =
379*61046927SAndroid Build Coastguard Worker          container_of(params, const struct wsi_drm_image_params, base);
380*61046927SAndroid Build Coastguard Worker       return wsi_drm_image_needs_buffer_blit(wsi, drm_params) ?
381*61046927SAndroid Build Coastguard Worker          WSI_SWAPCHAIN_BUFFER_BLIT : WSI_SWAPCHAIN_NO_BLIT;
382*61046927SAndroid Build Coastguard Worker    }
383*61046927SAndroid Build Coastguard Worker #endif
384*61046927SAndroid Build Coastguard Worker #ifdef _WIN32
385*61046927SAndroid Build Coastguard Worker    case WSI_IMAGE_TYPE_DXGI: {
386*61046927SAndroid Build Coastguard Worker       const struct wsi_dxgi_image_params *dxgi_params =
387*61046927SAndroid Build Coastguard Worker          container_of(params, const struct wsi_dxgi_image_params, base);
388*61046927SAndroid Build Coastguard Worker       return wsi_dxgi_image_needs_blit(wsi, dxgi_params, device);
389*61046927SAndroid Build Coastguard Worker    }
390*61046927SAndroid Build Coastguard Worker #endif
391*61046927SAndroid Build Coastguard Worker    default:
392*61046927SAndroid Build Coastguard Worker       unreachable("Invalid image type");
393*61046927SAndroid Build Coastguard Worker    }
394*61046927SAndroid Build Coastguard Worker }
395*61046927SAndroid Build Coastguard Worker 
396*61046927SAndroid Build Coastguard Worker static VkResult
configure_image(const struct wsi_swapchain * chain,const VkSwapchainCreateInfoKHR * pCreateInfo,const struct wsi_base_image_params * params,struct wsi_image_info * info)397*61046927SAndroid Build Coastguard Worker configure_image(const struct wsi_swapchain *chain,
398*61046927SAndroid Build Coastguard Worker                 const VkSwapchainCreateInfoKHR *pCreateInfo,
399*61046927SAndroid Build Coastguard Worker                 const struct wsi_base_image_params *params,
400*61046927SAndroid Build Coastguard Worker                 struct wsi_image_info *info)
401*61046927SAndroid Build Coastguard Worker {
402*61046927SAndroid Build Coastguard Worker    info->image_type = params->image_type;
403*61046927SAndroid Build Coastguard Worker    switch (params->image_type) {
404*61046927SAndroid Build Coastguard Worker    case WSI_IMAGE_TYPE_CPU: {
405*61046927SAndroid Build Coastguard Worker       const struct wsi_cpu_image_params *cpu_params =
406*61046927SAndroid Build Coastguard Worker          container_of(params, const struct wsi_cpu_image_params, base);
407*61046927SAndroid Build Coastguard Worker       return wsi_configure_cpu_image(chain, pCreateInfo, cpu_params, info);
408*61046927SAndroid Build Coastguard Worker    }
409*61046927SAndroid Build Coastguard Worker #ifdef HAVE_LIBDRM
410*61046927SAndroid Build Coastguard Worker    case WSI_IMAGE_TYPE_DRM: {
411*61046927SAndroid Build Coastguard Worker       const struct wsi_drm_image_params *drm_params =
412*61046927SAndroid Build Coastguard Worker          container_of(params, const struct wsi_drm_image_params, base);
413*61046927SAndroid Build Coastguard Worker       return wsi_drm_configure_image(chain, pCreateInfo, drm_params, info);
414*61046927SAndroid Build Coastguard Worker    }
415*61046927SAndroid Build Coastguard Worker #endif
416*61046927SAndroid Build Coastguard Worker #ifdef _WIN32
417*61046927SAndroid Build Coastguard Worker    case WSI_IMAGE_TYPE_DXGI: {
418*61046927SAndroid Build Coastguard Worker       const struct wsi_dxgi_image_params *dxgi_params =
419*61046927SAndroid Build Coastguard Worker          container_of(params, const struct wsi_dxgi_image_params, base);
420*61046927SAndroid Build Coastguard Worker       return wsi_dxgi_configure_image(chain, pCreateInfo, dxgi_params, info);
421*61046927SAndroid Build Coastguard Worker    }
422*61046927SAndroid Build Coastguard Worker #endif
423*61046927SAndroid Build Coastguard Worker    default:
424*61046927SAndroid Build Coastguard Worker       unreachable("Invalid image type");
425*61046927SAndroid Build Coastguard Worker    }
426*61046927SAndroid Build Coastguard Worker }
427*61046927SAndroid Build Coastguard Worker 
428*61046927SAndroid Build Coastguard Worker VkResult
wsi_swapchain_init(const struct wsi_device * wsi,struct wsi_swapchain * chain,VkDevice _device,const VkSwapchainCreateInfoKHR * pCreateInfo,const struct wsi_base_image_params * image_params,const VkAllocationCallbacks * pAllocator)429*61046927SAndroid Build Coastguard Worker wsi_swapchain_init(const struct wsi_device *wsi,
430*61046927SAndroid Build Coastguard Worker                    struct wsi_swapchain *chain,
431*61046927SAndroid Build Coastguard Worker                    VkDevice _device,
432*61046927SAndroid Build Coastguard Worker                    const VkSwapchainCreateInfoKHR *pCreateInfo,
433*61046927SAndroid Build Coastguard Worker                    const struct wsi_base_image_params *image_params,
434*61046927SAndroid Build Coastguard Worker                    const VkAllocationCallbacks *pAllocator)
435*61046927SAndroid Build Coastguard Worker {
436*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_device, device, _device);
437*61046927SAndroid Build Coastguard Worker    VkResult result;
438*61046927SAndroid Build Coastguard Worker 
439*61046927SAndroid Build Coastguard Worker    memset(chain, 0, sizeof(*chain));
440*61046927SAndroid Build Coastguard Worker 
441*61046927SAndroid Build Coastguard Worker    vk_object_base_init(device, &chain->base, VK_OBJECT_TYPE_SWAPCHAIN_KHR);
442*61046927SAndroid Build Coastguard Worker 
443*61046927SAndroid Build Coastguard Worker    chain->wsi = wsi;
444*61046927SAndroid Build Coastguard Worker    chain->device = _device;
445*61046927SAndroid Build Coastguard Worker    chain->alloc = *pAllocator;
446*61046927SAndroid Build Coastguard Worker    chain->blit.type = get_blit_type(wsi, image_params, _device);
447*61046927SAndroid Build Coastguard Worker 
448*61046927SAndroid Build Coastguard Worker    chain->blit.queue = VK_NULL_HANDLE;
449*61046927SAndroid Build Coastguard Worker    if (chain->blit.type != WSI_SWAPCHAIN_NO_BLIT && wsi->get_blit_queue)
450*61046927SAndroid Build Coastguard Worker       chain->blit.queue = wsi->get_blit_queue(_device);
451*61046927SAndroid Build Coastguard Worker 
452*61046927SAndroid Build Coastguard Worker    int cmd_pools_count = chain->blit.queue != VK_NULL_HANDLE ? 1 : wsi->queue_family_count;
453*61046927SAndroid Build Coastguard Worker 
454*61046927SAndroid Build Coastguard Worker    chain->cmd_pools =
455*61046927SAndroid Build Coastguard Worker       vk_zalloc(pAllocator, sizeof(VkCommandPool) * cmd_pools_count, 8,
456*61046927SAndroid Build Coastguard Worker                 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
457*61046927SAndroid Build Coastguard Worker    if (!chain->cmd_pools)
458*61046927SAndroid Build Coastguard Worker       return VK_ERROR_OUT_OF_HOST_MEMORY;
459*61046927SAndroid Build Coastguard Worker 
460*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < cmd_pools_count; i++) {
461*61046927SAndroid Build Coastguard Worker       int queue_family_index = i;
462*61046927SAndroid Build Coastguard Worker 
463*61046927SAndroid Build Coastguard Worker       if (chain->blit.queue != VK_NULL_HANDLE) {
464*61046927SAndroid Build Coastguard Worker          VK_FROM_HANDLE(vk_queue, queue, chain->blit.queue);
465*61046927SAndroid Build Coastguard Worker          queue_family_index = queue->queue_family_index;
466*61046927SAndroid Build Coastguard Worker       } else {
467*61046927SAndroid Build Coastguard Worker          /* Queues returned by get_blit_queue() might not be listed in
468*61046927SAndroid Build Coastguard Worker           * GetPhysicalDeviceQueueFamilyProperties, so this check is skipped for those queues.
469*61046927SAndroid Build Coastguard Worker           */
470*61046927SAndroid Build Coastguard Worker          if (!(wsi->queue_supports_blit & BITFIELD64_BIT(queue_family_index)))
471*61046927SAndroid Build Coastguard Worker             continue;
472*61046927SAndroid Build Coastguard Worker       }
473*61046927SAndroid Build Coastguard Worker 
474*61046927SAndroid Build Coastguard Worker       const VkCommandPoolCreateInfo cmd_pool_info = {
475*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
476*61046927SAndroid Build Coastguard Worker          .pNext = NULL,
477*61046927SAndroid Build Coastguard Worker          .flags = 0,
478*61046927SAndroid Build Coastguard Worker          .queueFamilyIndex = queue_family_index,
479*61046927SAndroid Build Coastguard Worker       };
480*61046927SAndroid Build Coastguard Worker       result = wsi->CreateCommandPool(_device, &cmd_pool_info, &chain->alloc,
481*61046927SAndroid Build Coastguard Worker                                       &chain->cmd_pools[i]);
482*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
483*61046927SAndroid Build Coastguard Worker          goto fail;
484*61046927SAndroid Build Coastguard Worker    }
485*61046927SAndroid Build Coastguard Worker 
486*61046927SAndroid Build Coastguard Worker    result = configure_image(chain, pCreateInfo, image_params,
487*61046927SAndroid Build Coastguard Worker                             &chain->image_info);
488*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
489*61046927SAndroid Build Coastguard Worker       goto fail;
490*61046927SAndroid Build Coastguard Worker 
491*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
492*61046927SAndroid Build Coastguard Worker 
493*61046927SAndroid Build Coastguard Worker fail:
494*61046927SAndroid Build Coastguard Worker    wsi_swapchain_finish(chain);
495*61046927SAndroid Build Coastguard Worker    return result;
496*61046927SAndroid Build Coastguard Worker }
497*61046927SAndroid Build Coastguard Worker 
498*61046927SAndroid Build Coastguard Worker static bool
wsi_swapchain_is_present_mode_supported(struct wsi_device * wsi,const VkSwapchainCreateInfoKHR * pCreateInfo,VkPresentModeKHR mode)499*61046927SAndroid Build Coastguard Worker wsi_swapchain_is_present_mode_supported(struct wsi_device *wsi,
500*61046927SAndroid Build Coastguard Worker                                         const VkSwapchainCreateInfoKHR *pCreateInfo,
501*61046927SAndroid Build Coastguard Worker                                         VkPresentModeKHR mode)
502*61046927SAndroid Build Coastguard Worker {
503*61046927SAndroid Build Coastguard Worker       ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pCreateInfo->surface);
504*61046927SAndroid Build Coastguard Worker       struct wsi_interface *iface = wsi->wsi[surface->platform];
505*61046927SAndroid Build Coastguard Worker       VkPresentModeKHR *present_modes;
506*61046927SAndroid Build Coastguard Worker       uint32_t present_mode_count;
507*61046927SAndroid Build Coastguard Worker       bool supported = false;
508*61046927SAndroid Build Coastguard Worker       VkResult result;
509*61046927SAndroid Build Coastguard Worker 
510*61046927SAndroid Build Coastguard Worker       result = iface->get_present_modes(surface, wsi, &present_mode_count, NULL);
511*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
512*61046927SAndroid Build Coastguard Worker          return supported;
513*61046927SAndroid Build Coastguard Worker 
514*61046927SAndroid Build Coastguard Worker       present_modes = malloc(present_mode_count * sizeof(*present_modes));
515*61046927SAndroid Build Coastguard Worker       if (!present_modes)
516*61046927SAndroid Build Coastguard Worker          return supported;
517*61046927SAndroid Build Coastguard Worker 
518*61046927SAndroid Build Coastguard Worker       result = iface->get_present_modes(surface, wsi, &present_mode_count,
519*61046927SAndroid Build Coastguard Worker                                         present_modes);
520*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
521*61046927SAndroid Build Coastguard Worker          goto fail;
522*61046927SAndroid Build Coastguard Worker 
523*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < present_mode_count; i++) {
524*61046927SAndroid Build Coastguard Worker          if (present_modes[i] == mode) {
525*61046927SAndroid Build Coastguard Worker             supported = true;
526*61046927SAndroid Build Coastguard Worker             break;
527*61046927SAndroid Build Coastguard Worker          }
528*61046927SAndroid Build Coastguard Worker       }
529*61046927SAndroid Build Coastguard Worker 
530*61046927SAndroid Build Coastguard Worker fail:
531*61046927SAndroid Build Coastguard Worker       free(present_modes);
532*61046927SAndroid Build Coastguard Worker       return supported;
533*61046927SAndroid Build Coastguard Worker }
534*61046927SAndroid Build Coastguard Worker 
535*61046927SAndroid Build Coastguard Worker enum VkPresentModeKHR
wsi_swapchain_get_present_mode(struct wsi_device * wsi,const VkSwapchainCreateInfoKHR * pCreateInfo)536*61046927SAndroid Build Coastguard Worker wsi_swapchain_get_present_mode(struct wsi_device *wsi,
537*61046927SAndroid Build Coastguard Worker                                const VkSwapchainCreateInfoKHR *pCreateInfo)
538*61046927SAndroid Build Coastguard Worker {
539*61046927SAndroid Build Coastguard Worker    if (wsi->override_present_mode == VK_PRESENT_MODE_MAX_ENUM_KHR)
540*61046927SAndroid Build Coastguard Worker       return pCreateInfo->presentMode;
541*61046927SAndroid Build Coastguard Worker 
542*61046927SAndroid Build Coastguard Worker    if (!wsi_swapchain_is_present_mode_supported(wsi, pCreateInfo,
543*61046927SAndroid Build Coastguard Worker                                                 wsi->override_present_mode)) {
544*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "Unsupported MESA_VK_WSI_PRESENT_MODE value!\n");
545*61046927SAndroid Build Coastguard Worker       return pCreateInfo->presentMode;
546*61046927SAndroid Build Coastguard Worker    }
547*61046927SAndroid Build Coastguard Worker 
548*61046927SAndroid Build Coastguard Worker    return wsi->override_present_mode;
549*61046927SAndroid Build Coastguard Worker }
550*61046927SAndroid Build Coastguard Worker 
551*61046927SAndroid Build Coastguard Worker void
wsi_swapchain_finish(struct wsi_swapchain * chain)552*61046927SAndroid Build Coastguard Worker wsi_swapchain_finish(struct wsi_swapchain *chain)
553*61046927SAndroid Build Coastguard Worker {
554*61046927SAndroid Build Coastguard Worker    wsi_destroy_image_info(chain, &chain->image_info);
555*61046927SAndroid Build Coastguard Worker 
556*61046927SAndroid Build Coastguard Worker    if (chain->fences) {
557*61046927SAndroid Build Coastguard Worker       for (unsigned i = 0; i < chain->image_count; i++)
558*61046927SAndroid Build Coastguard Worker          chain->wsi->DestroyFence(chain->device, chain->fences[i], &chain->alloc);
559*61046927SAndroid Build Coastguard Worker 
560*61046927SAndroid Build Coastguard Worker       vk_free(&chain->alloc, chain->fences);
561*61046927SAndroid Build Coastguard Worker    }
562*61046927SAndroid Build Coastguard Worker    if (chain->blit.semaphores) {
563*61046927SAndroid Build Coastguard Worker       for (unsigned i = 0; i < chain->image_count; i++)
564*61046927SAndroid Build Coastguard Worker          chain->wsi->DestroySemaphore(chain->device, chain->blit.semaphores[i], &chain->alloc);
565*61046927SAndroid Build Coastguard Worker 
566*61046927SAndroid Build Coastguard Worker       vk_free(&chain->alloc, chain->blit.semaphores);
567*61046927SAndroid Build Coastguard Worker    }
568*61046927SAndroid Build Coastguard Worker    chain->wsi->DestroySemaphore(chain->device, chain->dma_buf_semaphore,
569*61046927SAndroid Build Coastguard Worker                                 &chain->alloc);
570*61046927SAndroid Build Coastguard Worker    chain->wsi->DestroySemaphore(chain->device, chain->present_id_timeline,
571*61046927SAndroid Build Coastguard Worker                                 &chain->alloc);
572*61046927SAndroid Build Coastguard Worker 
573*61046927SAndroid Build Coastguard Worker    int cmd_pools_count = chain->blit.queue != VK_NULL_HANDLE ?
574*61046927SAndroid Build Coastguard Worker       1 : chain->wsi->queue_family_count;
575*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < cmd_pools_count; i++) {
576*61046927SAndroid Build Coastguard Worker       if (!chain->cmd_pools[i])
577*61046927SAndroid Build Coastguard Worker          continue;
578*61046927SAndroid Build Coastguard Worker       chain->wsi->DestroyCommandPool(chain->device, chain->cmd_pools[i],
579*61046927SAndroid Build Coastguard Worker                                      &chain->alloc);
580*61046927SAndroid Build Coastguard Worker    }
581*61046927SAndroid Build Coastguard Worker    vk_free(&chain->alloc, chain->cmd_pools);
582*61046927SAndroid Build Coastguard Worker 
583*61046927SAndroid Build Coastguard Worker    vk_object_base_finish(&chain->base);
584*61046927SAndroid Build Coastguard Worker }
585*61046927SAndroid Build Coastguard Worker 
586*61046927SAndroid Build Coastguard Worker VkResult
wsi_configure_image(const struct wsi_swapchain * chain,const VkSwapchainCreateInfoKHR * pCreateInfo,VkExternalMemoryHandleTypeFlags handle_types,struct wsi_image_info * info)587*61046927SAndroid Build Coastguard Worker wsi_configure_image(const struct wsi_swapchain *chain,
588*61046927SAndroid Build Coastguard Worker                     const VkSwapchainCreateInfoKHR *pCreateInfo,
589*61046927SAndroid Build Coastguard Worker                     VkExternalMemoryHandleTypeFlags handle_types,
590*61046927SAndroid Build Coastguard Worker                     struct wsi_image_info *info)
591*61046927SAndroid Build Coastguard Worker {
592*61046927SAndroid Build Coastguard Worker    memset(info, 0, sizeof(*info));
593*61046927SAndroid Build Coastguard Worker    uint32_t queue_family_count = 1;
594*61046927SAndroid Build Coastguard Worker 
595*61046927SAndroid Build Coastguard Worker    if (pCreateInfo->imageSharingMode == VK_SHARING_MODE_CONCURRENT)
596*61046927SAndroid Build Coastguard Worker       queue_family_count = pCreateInfo->queueFamilyIndexCount;
597*61046927SAndroid Build Coastguard Worker 
598*61046927SAndroid Build Coastguard Worker    /*
599*61046927SAndroid Build Coastguard Worker     * TODO: there should be no reason to allocate this, but
600*61046927SAndroid Build Coastguard Worker     * 15331 shows that games crashed without doing this.
601*61046927SAndroid Build Coastguard Worker     */
602*61046927SAndroid Build Coastguard Worker    uint32_t *queue_family_indices =
603*61046927SAndroid Build Coastguard Worker       vk_alloc(&chain->alloc,
604*61046927SAndroid Build Coastguard Worker                sizeof(*queue_family_indices) *
605*61046927SAndroid Build Coastguard Worker                queue_family_count,
606*61046927SAndroid Build Coastguard Worker                8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
607*61046927SAndroid Build Coastguard Worker    if (!queue_family_indices)
608*61046927SAndroid Build Coastguard Worker       goto err_oom;
609*61046927SAndroid Build Coastguard Worker 
610*61046927SAndroid Build Coastguard Worker    if (pCreateInfo->imageSharingMode == VK_SHARING_MODE_CONCURRENT)
611*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < pCreateInfo->queueFamilyIndexCount; i++)
612*61046927SAndroid Build Coastguard Worker          queue_family_indices[i] = pCreateInfo->pQueueFamilyIndices[i];
613*61046927SAndroid Build Coastguard Worker 
614*61046927SAndroid Build Coastguard Worker    info->create = (VkImageCreateInfo) {
615*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
616*61046927SAndroid Build Coastguard Worker       .flags = VK_IMAGE_CREATE_ALIAS_BIT,
617*61046927SAndroid Build Coastguard Worker       .imageType = VK_IMAGE_TYPE_2D,
618*61046927SAndroid Build Coastguard Worker       .format = pCreateInfo->imageFormat,
619*61046927SAndroid Build Coastguard Worker       .extent = {
620*61046927SAndroid Build Coastguard Worker          .width = pCreateInfo->imageExtent.width,
621*61046927SAndroid Build Coastguard Worker          .height = pCreateInfo->imageExtent.height,
622*61046927SAndroid Build Coastguard Worker          .depth = 1,
623*61046927SAndroid Build Coastguard Worker       },
624*61046927SAndroid Build Coastguard Worker       .mipLevels = 1,
625*61046927SAndroid Build Coastguard Worker       .arrayLayers = 1,
626*61046927SAndroid Build Coastguard Worker       .samples = VK_SAMPLE_COUNT_1_BIT,
627*61046927SAndroid Build Coastguard Worker       .tiling = VK_IMAGE_TILING_OPTIMAL,
628*61046927SAndroid Build Coastguard Worker       .usage = pCreateInfo->imageUsage,
629*61046927SAndroid Build Coastguard Worker       .sharingMode = pCreateInfo->imageSharingMode,
630*61046927SAndroid Build Coastguard Worker       .queueFamilyIndexCount = queue_family_count,
631*61046927SAndroid Build Coastguard Worker       .pQueueFamilyIndices = queue_family_indices,
632*61046927SAndroid Build Coastguard Worker       .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
633*61046927SAndroid Build Coastguard Worker    };
634*61046927SAndroid Build Coastguard Worker 
635*61046927SAndroid Build Coastguard Worker    if (handle_types != 0) {
636*61046927SAndroid Build Coastguard Worker       info->ext_mem = (VkExternalMemoryImageCreateInfo) {
637*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
638*61046927SAndroid Build Coastguard Worker          .handleTypes = handle_types,
639*61046927SAndroid Build Coastguard Worker       };
640*61046927SAndroid Build Coastguard Worker       __vk_append_struct(&info->create, &info->ext_mem);
641*61046927SAndroid Build Coastguard Worker    }
642*61046927SAndroid Build Coastguard Worker 
643*61046927SAndroid Build Coastguard Worker    info->wsi = (struct wsi_image_create_info) {
644*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO_MESA,
645*61046927SAndroid Build Coastguard Worker    };
646*61046927SAndroid Build Coastguard Worker    __vk_append_struct(&info->create, &info->wsi);
647*61046927SAndroid Build Coastguard Worker 
648*61046927SAndroid Build Coastguard Worker    if (pCreateInfo->flags & VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR) {
649*61046927SAndroid Build Coastguard Worker       info->create.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT |
650*61046927SAndroid Build Coastguard Worker                             VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
651*61046927SAndroid Build Coastguard Worker 
652*61046927SAndroid Build Coastguard Worker       const VkImageFormatListCreateInfo *format_list_in =
653*61046927SAndroid Build Coastguard Worker          vk_find_struct_const(pCreateInfo->pNext,
654*61046927SAndroid Build Coastguard Worker                               IMAGE_FORMAT_LIST_CREATE_INFO);
655*61046927SAndroid Build Coastguard Worker 
656*61046927SAndroid Build Coastguard Worker       assume(format_list_in && format_list_in->viewFormatCount > 0);
657*61046927SAndroid Build Coastguard Worker 
658*61046927SAndroid Build Coastguard Worker       const uint32_t view_format_count = format_list_in->viewFormatCount;
659*61046927SAndroid Build Coastguard Worker       VkFormat *view_formats =
660*61046927SAndroid Build Coastguard Worker          vk_alloc(&chain->alloc, sizeof(VkFormat) * view_format_count,
661*61046927SAndroid Build Coastguard Worker                   8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
662*61046927SAndroid Build Coastguard Worker       if (!view_formats)
663*61046927SAndroid Build Coastguard Worker          goto err_oom;
664*61046927SAndroid Build Coastguard Worker 
665*61046927SAndroid Build Coastguard Worker       ASSERTED bool format_found = false;
666*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < format_list_in->viewFormatCount; i++) {
667*61046927SAndroid Build Coastguard Worker          if (pCreateInfo->imageFormat == format_list_in->pViewFormats[i])
668*61046927SAndroid Build Coastguard Worker             format_found = true;
669*61046927SAndroid Build Coastguard Worker          view_formats[i] = format_list_in->pViewFormats[i];
670*61046927SAndroid Build Coastguard Worker       }
671*61046927SAndroid Build Coastguard Worker       assert(format_found);
672*61046927SAndroid Build Coastguard Worker 
673*61046927SAndroid Build Coastguard Worker       info->format_list = (VkImageFormatListCreateInfo) {
674*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO,
675*61046927SAndroid Build Coastguard Worker          .viewFormatCount = view_format_count,
676*61046927SAndroid Build Coastguard Worker          .pViewFormats = view_formats,
677*61046927SAndroid Build Coastguard Worker       };
678*61046927SAndroid Build Coastguard Worker       __vk_append_struct(&info->create, &info->format_list);
679*61046927SAndroid Build Coastguard Worker    }
680*61046927SAndroid Build Coastguard Worker 
681*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
682*61046927SAndroid Build Coastguard Worker 
683*61046927SAndroid Build Coastguard Worker err_oom:
684*61046927SAndroid Build Coastguard Worker    wsi_destroy_image_info(chain, info);
685*61046927SAndroid Build Coastguard Worker    return VK_ERROR_OUT_OF_HOST_MEMORY;
686*61046927SAndroid Build Coastguard Worker }
687*61046927SAndroid Build Coastguard Worker 
688*61046927SAndroid Build Coastguard Worker void
wsi_destroy_image_info(const struct wsi_swapchain * chain,struct wsi_image_info * info)689*61046927SAndroid Build Coastguard Worker wsi_destroy_image_info(const struct wsi_swapchain *chain,
690*61046927SAndroid Build Coastguard Worker                        struct wsi_image_info *info)
691*61046927SAndroid Build Coastguard Worker {
692*61046927SAndroid Build Coastguard Worker    if (info->create.pQueueFamilyIndices != NULL) {
693*61046927SAndroid Build Coastguard Worker       vk_free(&chain->alloc, (void *)info->create.pQueueFamilyIndices);
694*61046927SAndroid Build Coastguard Worker       info->create.pQueueFamilyIndices = NULL;
695*61046927SAndroid Build Coastguard Worker    }
696*61046927SAndroid Build Coastguard Worker    if (info->format_list.pViewFormats != NULL) {
697*61046927SAndroid Build Coastguard Worker       vk_free(&chain->alloc, (void *)info->format_list.pViewFormats);
698*61046927SAndroid Build Coastguard Worker       info->format_list.pViewFormats = NULL;
699*61046927SAndroid Build Coastguard Worker    }
700*61046927SAndroid Build Coastguard Worker    if (info->drm_mod_list.pDrmFormatModifiers != NULL) {
701*61046927SAndroid Build Coastguard Worker       vk_free(&chain->alloc, (void *)info->drm_mod_list.pDrmFormatModifiers);
702*61046927SAndroid Build Coastguard Worker       info->drm_mod_list.pDrmFormatModifiers = NULL;
703*61046927SAndroid Build Coastguard Worker    }
704*61046927SAndroid Build Coastguard Worker    if (info->modifier_props != NULL) {
705*61046927SAndroid Build Coastguard Worker       vk_free(&chain->alloc, info->modifier_props);
706*61046927SAndroid Build Coastguard Worker       info->modifier_props = NULL;
707*61046927SAndroid Build Coastguard Worker    }
708*61046927SAndroid Build Coastguard Worker }
709*61046927SAndroid Build Coastguard Worker 
710*61046927SAndroid Build Coastguard Worker VkResult
wsi_create_image(const struct wsi_swapchain * chain,const struct wsi_image_info * info,struct wsi_image * image)711*61046927SAndroid Build Coastguard Worker wsi_create_image(const struct wsi_swapchain *chain,
712*61046927SAndroid Build Coastguard Worker                  const struct wsi_image_info *info,
713*61046927SAndroid Build Coastguard Worker                  struct wsi_image *image)
714*61046927SAndroid Build Coastguard Worker {
715*61046927SAndroid Build Coastguard Worker    const struct wsi_device *wsi = chain->wsi;
716*61046927SAndroid Build Coastguard Worker    VkResult result;
717*61046927SAndroid Build Coastguard Worker 
718*61046927SAndroid Build Coastguard Worker    memset(image, 0, sizeof(*image));
719*61046927SAndroid Build Coastguard Worker 
720*61046927SAndroid Build Coastguard Worker #ifndef _WIN32
721*61046927SAndroid Build Coastguard Worker    image->dma_buf_fd = -1;
722*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < WSI_ES_COUNT; i++)
723*61046927SAndroid Build Coastguard Worker       image->explicit_sync[i].fd = -1;
724*61046927SAndroid Build Coastguard Worker #endif
725*61046927SAndroid Build Coastguard Worker 
726*61046927SAndroid Build Coastguard Worker    result = wsi->CreateImage(chain->device, &info->create,
727*61046927SAndroid Build Coastguard Worker                              &chain->alloc, &image->image);
728*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
729*61046927SAndroid Build Coastguard Worker       goto fail;
730*61046927SAndroid Build Coastguard Worker 
731*61046927SAndroid Build Coastguard Worker    result = info->create_mem(chain, info, image);
732*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
733*61046927SAndroid Build Coastguard Worker       goto fail;
734*61046927SAndroid Build Coastguard Worker 
735*61046927SAndroid Build Coastguard Worker    result = wsi->BindImageMemory(chain->device, image->image,
736*61046927SAndroid Build Coastguard Worker                                  image->memory, 0);
737*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
738*61046927SAndroid Build Coastguard Worker       goto fail;
739*61046927SAndroid Build Coastguard Worker 
740*61046927SAndroid Build Coastguard Worker    if (info->finish_create) {
741*61046927SAndroid Build Coastguard Worker       result = info->finish_create(chain, info, image);
742*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
743*61046927SAndroid Build Coastguard Worker          goto fail;
744*61046927SAndroid Build Coastguard Worker    }
745*61046927SAndroid Build Coastguard Worker 
746*61046927SAndroid Build Coastguard Worker    if (info->explicit_sync) {
747*61046927SAndroid Build Coastguard Worker #if HAVE_LIBDRM
748*61046927SAndroid Build Coastguard Worker       result = wsi_create_image_explicit_sync_drm(chain, image);
749*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
750*61046927SAndroid Build Coastguard Worker          goto fail;
751*61046927SAndroid Build Coastguard Worker #else
752*61046927SAndroid Build Coastguard Worker       result = VK_ERROR_FEATURE_NOT_PRESENT;
753*61046927SAndroid Build Coastguard Worker       goto fail;
754*61046927SAndroid Build Coastguard Worker #endif
755*61046927SAndroid Build Coastguard Worker    }
756*61046927SAndroid Build Coastguard Worker 
757*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
758*61046927SAndroid Build Coastguard Worker 
759*61046927SAndroid Build Coastguard Worker fail:
760*61046927SAndroid Build Coastguard Worker    wsi_destroy_image(chain, image);
761*61046927SAndroid Build Coastguard Worker    return result;
762*61046927SAndroid Build Coastguard Worker }
763*61046927SAndroid Build Coastguard Worker 
764*61046927SAndroid Build Coastguard Worker void
wsi_destroy_image(const struct wsi_swapchain * chain,struct wsi_image * image)765*61046927SAndroid Build Coastguard Worker wsi_destroy_image(const struct wsi_swapchain *chain,
766*61046927SAndroid Build Coastguard Worker                   struct wsi_image *image)
767*61046927SAndroid Build Coastguard Worker {
768*61046927SAndroid Build Coastguard Worker    const struct wsi_device *wsi = chain->wsi;
769*61046927SAndroid Build Coastguard Worker 
770*61046927SAndroid Build Coastguard Worker #ifndef _WIN32
771*61046927SAndroid Build Coastguard Worker    if (image->dma_buf_fd >= 0)
772*61046927SAndroid Build Coastguard Worker       close(image->dma_buf_fd);
773*61046927SAndroid Build Coastguard Worker #endif
774*61046927SAndroid Build Coastguard Worker 
775*61046927SAndroid Build Coastguard Worker    if (image->explicit_sync[WSI_ES_ACQUIRE].semaphore) {
776*61046927SAndroid Build Coastguard Worker #if HAVE_LIBDRM
777*61046927SAndroid Build Coastguard Worker       wsi_destroy_image_explicit_sync_drm(chain, image);
778*61046927SAndroid Build Coastguard Worker #endif
779*61046927SAndroid Build Coastguard Worker    }
780*61046927SAndroid Build Coastguard Worker 
781*61046927SAndroid Build Coastguard Worker    if (image->cpu_map != NULL) {
782*61046927SAndroid Build Coastguard Worker       wsi->UnmapMemory(chain->device, image->blit.buffer != VK_NULL_HANDLE ?
783*61046927SAndroid Build Coastguard Worker                                       image->blit.memory : image->memory);
784*61046927SAndroid Build Coastguard Worker    }
785*61046927SAndroid Build Coastguard Worker 
786*61046927SAndroid Build Coastguard Worker    if (image->blit.cmd_buffers) {
787*61046927SAndroid Build Coastguard Worker       int cmd_buffer_count =
788*61046927SAndroid Build Coastguard Worker          chain->blit.queue != VK_NULL_HANDLE ? 1 : wsi->queue_family_count;
789*61046927SAndroid Build Coastguard Worker 
790*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < cmd_buffer_count; i++) {
791*61046927SAndroid Build Coastguard Worker          if (!chain->cmd_pools[i])
792*61046927SAndroid Build Coastguard Worker             continue;
793*61046927SAndroid Build Coastguard Worker          wsi->FreeCommandBuffers(chain->device, chain->cmd_pools[i],
794*61046927SAndroid Build Coastguard Worker                                  1, &image->blit.cmd_buffers[i]);
795*61046927SAndroid Build Coastguard Worker       }
796*61046927SAndroid Build Coastguard Worker       vk_free(&chain->alloc, image->blit.cmd_buffers);
797*61046927SAndroid Build Coastguard Worker    }
798*61046927SAndroid Build Coastguard Worker 
799*61046927SAndroid Build Coastguard Worker    wsi->FreeMemory(chain->device, image->memory, &chain->alloc);
800*61046927SAndroid Build Coastguard Worker    wsi->DestroyImage(chain->device, image->image, &chain->alloc);
801*61046927SAndroid Build Coastguard Worker    wsi->DestroyImage(chain->device, image->blit.image, &chain->alloc);
802*61046927SAndroid Build Coastguard Worker    wsi->FreeMemory(chain->device, image->blit.memory, &chain->alloc);
803*61046927SAndroid Build Coastguard Worker    wsi->DestroyBuffer(chain->device, image->blit.buffer, &chain->alloc);
804*61046927SAndroid Build Coastguard Worker }
805*61046927SAndroid Build Coastguard Worker 
806*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
wsi_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,uint32_t queueFamilyIndex,VkSurfaceKHR _surface,VkBool32 * pSupported)807*61046927SAndroid Build Coastguard Worker wsi_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,
808*61046927SAndroid Build Coastguard Worker                                        uint32_t queueFamilyIndex,
809*61046927SAndroid Build Coastguard Worker                                        VkSurfaceKHR _surface,
810*61046927SAndroid Build Coastguard Worker                                        VkBool32 *pSupported)
811*61046927SAndroid Build Coastguard Worker {
812*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_physical_device, device, physicalDevice);
813*61046927SAndroid Build Coastguard Worker    ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
814*61046927SAndroid Build Coastguard Worker    struct wsi_device *wsi_device = device->wsi_device;
815*61046927SAndroid Build Coastguard Worker    struct wsi_interface *iface = wsi_device->wsi[surface->platform];
816*61046927SAndroid Build Coastguard Worker 
817*61046927SAndroid Build Coastguard Worker    VkResult res = iface->get_support(surface, wsi_device,
818*61046927SAndroid Build Coastguard Worker                                      queueFamilyIndex, pSupported);
819*61046927SAndroid Build Coastguard Worker    if (res == VK_SUCCESS) {
820*61046927SAndroid Build Coastguard Worker       bool blit = (wsi_device->queue_supports_blit & BITFIELD64_BIT(queueFamilyIndex)) != 0;
821*61046927SAndroid Build Coastguard Worker       *pSupported = (bool)*pSupported && blit;
822*61046927SAndroid Build Coastguard Worker    }
823*61046927SAndroid Build Coastguard Worker 
824*61046927SAndroid Build Coastguard Worker    return res;
825*61046927SAndroid Build Coastguard Worker }
826*61046927SAndroid Build Coastguard Worker 
827*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
wsi_GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR _surface,VkSurfaceCapabilitiesKHR * pSurfaceCapabilities)828*61046927SAndroid Build Coastguard Worker wsi_GetPhysicalDeviceSurfaceCapabilitiesKHR(
829*61046927SAndroid Build Coastguard Worker    VkPhysicalDevice physicalDevice,
830*61046927SAndroid Build Coastguard Worker    VkSurfaceKHR _surface,
831*61046927SAndroid Build Coastguard Worker    VkSurfaceCapabilitiesKHR *pSurfaceCapabilities)
832*61046927SAndroid Build Coastguard Worker {
833*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_physical_device, device, physicalDevice);
834*61046927SAndroid Build Coastguard Worker    ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
835*61046927SAndroid Build Coastguard Worker    struct wsi_device *wsi_device = device->wsi_device;
836*61046927SAndroid Build Coastguard Worker    struct wsi_interface *iface = wsi_device->wsi[surface->platform];
837*61046927SAndroid Build Coastguard Worker 
838*61046927SAndroid Build Coastguard Worker    VkSurfaceCapabilities2KHR caps2 = {
839*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR,
840*61046927SAndroid Build Coastguard Worker    };
841*61046927SAndroid Build Coastguard Worker 
842*61046927SAndroid Build Coastguard Worker    VkResult result = iface->get_capabilities2(surface, wsi_device, NULL, &caps2);
843*61046927SAndroid Build Coastguard Worker 
844*61046927SAndroid Build Coastguard Worker    if (result == VK_SUCCESS)
845*61046927SAndroid Build Coastguard Worker       *pSurfaceCapabilities = caps2.surfaceCapabilities;
846*61046927SAndroid Build Coastguard Worker 
847*61046927SAndroid Build Coastguard Worker    return result;
848*61046927SAndroid Build Coastguard Worker }
849*61046927SAndroid Build Coastguard Worker 
850*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
wsi_GetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,VkSurfaceCapabilities2KHR * pSurfaceCapabilities)851*61046927SAndroid Build Coastguard Worker wsi_GetPhysicalDeviceSurfaceCapabilities2KHR(
852*61046927SAndroid Build Coastguard Worker    VkPhysicalDevice physicalDevice,
853*61046927SAndroid Build Coastguard Worker    const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
854*61046927SAndroid Build Coastguard Worker    VkSurfaceCapabilities2KHR *pSurfaceCapabilities)
855*61046927SAndroid Build Coastguard Worker {
856*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_physical_device, device, physicalDevice);
857*61046927SAndroid Build Coastguard Worker    ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pSurfaceInfo->surface);
858*61046927SAndroid Build Coastguard Worker    struct wsi_device *wsi_device = device->wsi_device;
859*61046927SAndroid Build Coastguard Worker    struct wsi_interface *iface = wsi_device->wsi[surface->platform];
860*61046927SAndroid Build Coastguard Worker 
861*61046927SAndroid Build Coastguard Worker    return iface->get_capabilities2(surface, wsi_device, pSurfaceInfo->pNext,
862*61046927SAndroid Build Coastguard Worker                                    pSurfaceCapabilities);
863*61046927SAndroid Build Coastguard Worker }
864*61046927SAndroid Build Coastguard Worker 
865*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
wsi_GetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice,VkSurfaceKHR _surface,VkSurfaceCapabilities2EXT * pSurfaceCapabilities)866*61046927SAndroid Build Coastguard Worker wsi_GetPhysicalDeviceSurfaceCapabilities2EXT(
867*61046927SAndroid Build Coastguard Worker    VkPhysicalDevice physicalDevice,
868*61046927SAndroid Build Coastguard Worker    VkSurfaceKHR _surface,
869*61046927SAndroid Build Coastguard Worker    VkSurfaceCapabilities2EXT *pSurfaceCapabilities)
870*61046927SAndroid Build Coastguard Worker {
871*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_physical_device, device, physicalDevice);
872*61046927SAndroid Build Coastguard Worker    ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
873*61046927SAndroid Build Coastguard Worker    struct wsi_device *wsi_device = device->wsi_device;
874*61046927SAndroid Build Coastguard Worker    struct wsi_interface *iface = wsi_device->wsi[surface->platform];
875*61046927SAndroid Build Coastguard Worker 
876*61046927SAndroid Build Coastguard Worker    assert(pSurfaceCapabilities->sType ==
877*61046927SAndroid Build Coastguard Worker           VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT);
878*61046927SAndroid Build Coastguard Worker 
879*61046927SAndroid Build Coastguard Worker    struct wsi_surface_supported_counters counters = {
880*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_WSI_SURFACE_SUPPORTED_COUNTERS_MESA,
881*61046927SAndroid Build Coastguard Worker       .pNext = pSurfaceCapabilities->pNext,
882*61046927SAndroid Build Coastguard Worker       .supported_surface_counters = 0,
883*61046927SAndroid Build Coastguard Worker    };
884*61046927SAndroid Build Coastguard Worker 
885*61046927SAndroid Build Coastguard Worker    VkSurfaceCapabilities2KHR caps2 = {
886*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR,
887*61046927SAndroid Build Coastguard Worker       .pNext = &counters,
888*61046927SAndroid Build Coastguard Worker    };
889*61046927SAndroid Build Coastguard Worker 
890*61046927SAndroid Build Coastguard Worker    VkResult result = iface->get_capabilities2(surface, wsi_device, NULL, &caps2);
891*61046927SAndroid Build Coastguard Worker 
892*61046927SAndroid Build Coastguard Worker    if (result == VK_SUCCESS) {
893*61046927SAndroid Build Coastguard Worker       VkSurfaceCapabilities2EXT *ext_caps = pSurfaceCapabilities;
894*61046927SAndroid Build Coastguard Worker       VkSurfaceCapabilitiesKHR khr_caps = caps2.surfaceCapabilities;
895*61046927SAndroid Build Coastguard Worker 
896*61046927SAndroid Build Coastguard Worker       ext_caps->minImageCount = khr_caps.minImageCount;
897*61046927SAndroid Build Coastguard Worker       ext_caps->maxImageCount = khr_caps.maxImageCount;
898*61046927SAndroid Build Coastguard Worker       ext_caps->currentExtent = khr_caps.currentExtent;
899*61046927SAndroid Build Coastguard Worker       ext_caps->minImageExtent = khr_caps.minImageExtent;
900*61046927SAndroid Build Coastguard Worker       ext_caps->maxImageExtent = khr_caps.maxImageExtent;
901*61046927SAndroid Build Coastguard Worker       ext_caps->maxImageArrayLayers = khr_caps.maxImageArrayLayers;
902*61046927SAndroid Build Coastguard Worker       ext_caps->supportedTransforms = khr_caps.supportedTransforms;
903*61046927SAndroid Build Coastguard Worker       ext_caps->currentTransform = khr_caps.currentTransform;
904*61046927SAndroid Build Coastguard Worker       ext_caps->supportedCompositeAlpha = khr_caps.supportedCompositeAlpha;
905*61046927SAndroid Build Coastguard Worker       ext_caps->supportedUsageFlags = khr_caps.supportedUsageFlags;
906*61046927SAndroid Build Coastguard Worker       ext_caps->supportedSurfaceCounters = counters.supported_surface_counters;
907*61046927SAndroid Build Coastguard Worker    }
908*61046927SAndroid Build Coastguard Worker 
909*61046927SAndroid Build Coastguard Worker    return result;
910*61046927SAndroid Build Coastguard Worker }
911*61046927SAndroid Build Coastguard Worker 
912*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
wsi_GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR _surface,uint32_t * pSurfaceFormatCount,VkSurfaceFormatKHR * pSurfaceFormats)913*61046927SAndroid Build Coastguard Worker wsi_GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice,
914*61046927SAndroid Build Coastguard Worker                                        VkSurfaceKHR _surface,
915*61046927SAndroid Build Coastguard Worker                                        uint32_t *pSurfaceFormatCount,
916*61046927SAndroid Build Coastguard Worker                                        VkSurfaceFormatKHR *pSurfaceFormats)
917*61046927SAndroid Build Coastguard Worker {
918*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_physical_device, device, physicalDevice);
919*61046927SAndroid Build Coastguard Worker    ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
920*61046927SAndroid Build Coastguard Worker    struct wsi_device *wsi_device = device->wsi_device;
921*61046927SAndroid Build Coastguard Worker    struct wsi_interface *iface = wsi_device->wsi[surface->platform];
922*61046927SAndroid Build Coastguard Worker 
923*61046927SAndroid Build Coastguard Worker    return iface->get_formats(surface, wsi_device,
924*61046927SAndroid Build Coastguard Worker                              pSurfaceFormatCount, pSurfaceFormats);
925*61046927SAndroid Build Coastguard Worker }
926*61046927SAndroid Build Coastguard Worker 
927*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
wsi_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,uint32_t * pSurfaceFormatCount,VkSurfaceFormat2KHR * pSurfaceFormats)928*61046927SAndroid Build Coastguard Worker wsi_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
929*61046927SAndroid Build Coastguard Worker                                         const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,
930*61046927SAndroid Build Coastguard Worker                                         uint32_t *pSurfaceFormatCount,
931*61046927SAndroid Build Coastguard Worker                                         VkSurfaceFormat2KHR *pSurfaceFormats)
932*61046927SAndroid Build Coastguard Worker {
933*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_physical_device, device, physicalDevice);
934*61046927SAndroid Build Coastguard Worker    ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pSurfaceInfo->surface);
935*61046927SAndroid Build Coastguard Worker    struct wsi_device *wsi_device = device->wsi_device;
936*61046927SAndroid Build Coastguard Worker    struct wsi_interface *iface = wsi_device->wsi[surface->platform];
937*61046927SAndroid Build Coastguard Worker 
938*61046927SAndroid Build Coastguard Worker    return iface->get_formats2(surface, wsi_device, pSurfaceInfo->pNext,
939*61046927SAndroid Build Coastguard Worker                               pSurfaceFormatCount, pSurfaceFormats);
940*61046927SAndroid Build Coastguard Worker }
941*61046927SAndroid Build Coastguard Worker 
942*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
wsi_GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR _surface,uint32_t * pPresentModeCount,VkPresentModeKHR * pPresentModes)943*61046927SAndroid Build Coastguard Worker wsi_GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,
944*61046927SAndroid Build Coastguard Worker                                             VkSurfaceKHR _surface,
945*61046927SAndroid Build Coastguard Worker                                             uint32_t *pPresentModeCount,
946*61046927SAndroid Build Coastguard Worker                                             VkPresentModeKHR *pPresentModes)
947*61046927SAndroid Build Coastguard Worker {
948*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_physical_device, device, physicalDevice);
949*61046927SAndroid Build Coastguard Worker    ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
950*61046927SAndroid Build Coastguard Worker    struct wsi_device *wsi_device = device->wsi_device;
951*61046927SAndroid Build Coastguard Worker    struct wsi_interface *iface = wsi_device->wsi[surface->platform];
952*61046927SAndroid Build Coastguard Worker 
953*61046927SAndroid Build Coastguard Worker    return iface->get_present_modes(surface, wsi_device, pPresentModeCount,
954*61046927SAndroid Build Coastguard Worker                                    pPresentModes);
955*61046927SAndroid Build Coastguard Worker }
956*61046927SAndroid Build Coastguard Worker 
957*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
wsi_GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR _surface,uint32_t * pRectCount,VkRect2D * pRects)958*61046927SAndroid Build Coastguard Worker wsi_GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,
959*61046927SAndroid Build Coastguard Worker                                           VkSurfaceKHR _surface,
960*61046927SAndroid Build Coastguard Worker                                           uint32_t *pRectCount,
961*61046927SAndroid Build Coastguard Worker                                           VkRect2D *pRects)
962*61046927SAndroid Build Coastguard Worker {
963*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_physical_device, device, physicalDevice);
964*61046927SAndroid Build Coastguard Worker    ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
965*61046927SAndroid Build Coastguard Worker    struct wsi_device *wsi_device = device->wsi_device;
966*61046927SAndroid Build Coastguard Worker    struct wsi_interface *iface = wsi_device->wsi[surface->platform];
967*61046927SAndroid Build Coastguard Worker 
968*61046927SAndroid Build Coastguard Worker    return iface->get_present_rectangles(surface, wsi_device,
969*61046927SAndroid Build Coastguard Worker                                         pRectCount, pRects);
970*61046927SAndroid Build Coastguard Worker }
971*61046927SAndroid Build Coastguard Worker 
972*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
wsi_CreateSwapchainKHR(VkDevice _device,const VkSwapchainCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSwapchainKHR * pSwapchain)973*61046927SAndroid Build Coastguard Worker wsi_CreateSwapchainKHR(VkDevice _device,
974*61046927SAndroid Build Coastguard Worker                        const VkSwapchainCreateInfoKHR *pCreateInfo,
975*61046927SAndroid Build Coastguard Worker                        const VkAllocationCallbacks *pAllocator,
976*61046927SAndroid Build Coastguard Worker                        VkSwapchainKHR *pSwapchain)
977*61046927SAndroid Build Coastguard Worker {
978*61046927SAndroid Build Coastguard Worker    MESA_TRACE_FUNC();
979*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_device, device, _device);
980*61046927SAndroid Build Coastguard Worker    ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pCreateInfo->surface);
981*61046927SAndroid Build Coastguard Worker    struct wsi_device *wsi_device = device->physical->wsi_device;
982*61046927SAndroid Build Coastguard Worker    struct wsi_interface *iface = wsi_device->force_headless_swapchain ?
983*61046927SAndroid Build Coastguard Worker       wsi_device->wsi[VK_ICD_WSI_PLATFORM_HEADLESS] :
984*61046927SAndroid Build Coastguard Worker       wsi_device->wsi[surface->platform];
985*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc;
986*61046927SAndroid Build Coastguard Worker    struct wsi_swapchain *swapchain;
987*61046927SAndroid Build Coastguard Worker 
988*61046927SAndroid Build Coastguard Worker    if (pAllocator)
989*61046927SAndroid Build Coastguard Worker      alloc = pAllocator;
990*61046927SAndroid Build Coastguard Worker    else
991*61046927SAndroid Build Coastguard Worker      alloc = &device->alloc;
992*61046927SAndroid Build Coastguard Worker 
993*61046927SAndroid Build Coastguard Worker    VkSwapchainCreateInfoKHR info = *pCreateInfo;
994*61046927SAndroid Build Coastguard Worker 
995*61046927SAndroid Build Coastguard Worker    if (wsi_device->force_swapchain_to_currentExtent) {
996*61046927SAndroid Build Coastguard Worker       VkSurfaceCapabilities2KHR caps2 = {
997*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR,
998*61046927SAndroid Build Coastguard Worker       };
999*61046927SAndroid Build Coastguard Worker       iface->get_capabilities2(surface, wsi_device, NULL, &caps2);
1000*61046927SAndroid Build Coastguard Worker       info.imageExtent = caps2.surfaceCapabilities.currentExtent;
1001*61046927SAndroid Build Coastguard Worker    }
1002*61046927SAndroid Build Coastguard Worker 
1003*61046927SAndroid Build Coastguard Worker    /* Ignore DEFERRED_MEMORY_ALLOCATION_BIT. Would require deep plumbing to be able to take advantage of it.
1004*61046927SAndroid Build Coastguard Worker     * bool deferred_allocation = pCreateInfo->flags & VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT;
1005*61046927SAndroid Build Coastguard Worker     */
1006*61046927SAndroid Build Coastguard Worker 
1007*61046927SAndroid Build Coastguard Worker    VkResult result = iface->create_swapchain(surface, _device, wsi_device,
1008*61046927SAndroid Build Coastguard Worker                                              &info, alloc,
1009*61046927SAndroid Build Coastguard Worker                                              &swapchain);
1010*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1011*61046927SAndroid Build Coastguard Worker       return result;
1012*61046927SAndroid Build Coastguard Worker 
1013*61046927SAndroid Build Coastguard Worker    swapchain->fences = vk_zalloc(alloc,
1014*61046927SAndroid Build Coastguard Worker                                  sizeof (*swapchain->fences) * swapchain->image_count,
1015*61046927SAndroid Build Coastguard Worker                                  sizeof (*swapchain->fences),
1016*61046927SAndroid Build Coastguard Worker                                  VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1017*61046927SAndroid Build Coastguard Worker    if (!swapchain->fences) {
1018*61046927SAndroid Build Coastguard Worker       swapchain->destroy(swapchain, alloc);
1019*61046927SAndroid Build Coastguard Worker       return VK_ERROR_OUT_OF_HOST_MEMORY;
1020*61046927SAndroid Build Coastguard Worker    }
1021*61046927SAndroid Build Coastguard Worker 
1022*61046927SAndroid Build Coastguard Worker    if (wsi_device->khr_present_wait) {
1023*61046927SAndroid Build Coastguard Worker       const VkSemaphoreTypeCreateInfo type_info = {
1024*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
1025*61046927SAndroid Build Coastguard Worker          .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
1026*61046927SAndroid Build Coastguard Worker       };
1027*61046927SAndroid Build Coastguard Worker 
1028*61046927SAndroid Build Coastguard Worker       const VkSemaphoreCreateInfo sem_info = {
1029*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
1030*61046927SAndroid Build Coastguard Worker          .pNext = &type_info,
1031*61046927SAndroid Build Coastguard Worker          .flags = 0,
1032*61046927SAndroid Build Coastguard Worker       };
1033*61046927SAndroid Build Coastguard Worker 
1034*61046927SAndroid Build Coastguard Worker       /* We assume here that a driver exposing present_wait also exposes VK_KHR_timeline_semaphore. */
1035*61046927SAndroid Build Coastguard Worker       result = wsi_device->CreateSemaphore(_device, &sem_info, alloc, &swapchain->present_id_timeline);
1036*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS) {
1037*61046927SAndroid Build Coastguard Worker          swapchain->destroy(swapchain, alloc);
1038*61046927SAndroid Build Coastguard Worker          return VK_ERROR_OUT_OF_HOST_MEMORY;
1039*61046927SAndroid Build Coastguard Worker       }
1040*61046927SAndroid Build Coastguard Worker    }
1041*61046927SAndroid Build Coastguard Worker 
1042*61046927SAndroid Build Coastguard Worker    if (swapchain->blit.queue != VK_NULL_HANDLE) {
1043*61046927SAndroid Build Coastguard Worker       swapchain->blit.semaphores = vk_zalloc(alloc,
1044*61046927SAndroid Build Coastguard Worker                                          sizeof (*swapchain->blit.semaphores) * swapchain->image_count,
1045*61046927SAndroid Build Coastguard Worker                                          sizeof (*swapchain->blit.semaphores),
1046*61046927SAndroid Build Coastguard Worker                                          VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1047*61046927SAndroid Build Coastguard Worker       if (!swapchain->blit.semaphores) {
1048*61046927SAndroid Build Coastguard Worker          wsi_device->DestroySemaphore(_device, swapchain->present_id_timeline, alloc);
1049*61046927SAndroid Build Coastguard Worker          swapchain->destroy(swapchain, alloc);
1050*61046927SAndroid Build Coastguard Worker          return VK_ERROR_OUT_OF_HOST_MEMORY;
1051*61046927SAndroid Build Coastguard Worker       }
1052*61046927SAndroid Build Coastguard Worker    }
1053*61046927SAndroid Build Coastguard Worker 
1054*61046927SAndroid Build Coastguard Worker    *pSwapchain = wsi_swapchain_to_handle(swapchain);
1055*61046927SAndroid Build Coastguard Worker 
1056*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1057*61046927SAndroid Build Coastguard Worker }
1058*61046927SAndroid Build Coastguard Worker 
1059*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
wsi_DestroySwapchainKHR(VkDevice _device,VkSwapchainKHR _swapchain,const VkAllocationCallbacks * pAllocator)1060*61046927SAndroid Build Coastguard Worker wsi_DestroySwapchainKHR(VkDevice _device,
1061*61046927SAndroid Build Coastguard Worker                         VkSwapchainKHR _swapchain,
1062*61046927SAndroid Build Coastguard Worker                         const VkAllocationCallbacks *pAllocator)
1063*61046927SAndroid Build Coastguard Worker {
1064*61046927SAndroid Build Coastguard Worker    MESA_TRACE_FUNC();
1065*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_device, device, _device);
1066*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain);
1067*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc;
1068*61046927SAndroid Build Coastguard Worker 
1069*61046927SAndroid Build Coastguard Worker    if (!swapchain)
1070*61046927SAndroid Build Coastguard Worker       return;
1071*61046927SAndroid Build Coastguard Worker 
1072*61046927SAndroid Build Coastguard Worker    if (pAllocator)
1073*61046927SAndroid Build Coastguard Worker      alloc = pAllocator;
1074*61046927SAndroid Build Coastguard Worker    else
1075*61046927SAndroid Build Coastguard Worker      alloc = &device->alloc;
1076*61046927SAndroid Build Coastguard Worker 
1077*61046927SAndroid Build Coastguard Worker    swapchain->destroy(swapchain, alloc);
1078*61046927SAndroid Build Coastguard Worker }
1079*61046927SAndroid Build Coastguard Worker 
1080*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
wsi_ReleaseSwapchainImagesEXT(VkDevice _device,const VkReleaseSwapchainImagesInfoEXT * pReleaseInfo)1081*61046927SAndroid Build Coastguard Worker wsi_ReleaseSwapchainImagesEXT(VkDevice _device,
1082*61046927SAndroid Build Coastguard Worker                               const VkReleaseSwapchainImagesInfoEXT *pReleaseInfo)
1083*61046927SAndroid Build Coastguard Worker {
1084*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(wsi_swapchain, swapchain, pReleaseInfo->swapchain);
1085*61046927SAndroid Build Coastguard Worker 
1086*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < pReleaseInfo->imageIndexCount; i++) {
1087*61046927SAndroid Build Coastguard Worker       uint32_t index = pReleaseInfo->pImageIndices[i];
1088*61046927SAndroid Build Coastguard Worker       assert(index < swapchain->image_count);
1089*61046927SAndroid Build Coastguard Worker       struct wsi_image *image = swapchain->get_wsi_image(swapchain, index);
1090*61046927SAndroid Build Coastguard Worker       assert(image->acquired);
1091*61046927SAndroid Build Coastguard Worker       image->acquired = false;
1092*61046927SAndroid Build Coastguard Worker    }
1093*61046927SAndroid Build Coastguard Worker 
1094*61046927SAndroid Build Coastguard Worker    VkResult result = swapchain->release_images(swapchain,
1095*61046927SAndroid Build Coastguard Worker                                                pReleaseInfo->imageIndexCount,
1096*61046927SAndroid Build Coastguard Worker                                                pReleaseInfo->pImageIndices);
1097*61046927SAndroid Build Coastguard Worker 
1098*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1099*61046927SAndroid Build Coastguard Worker       return result;
1100*61046927SAndroid Build Coastguard Worker 
1101*61046927SAndroid Build Coastguard Worker    if (swapchain->wsi->set_memory_ownership) {
1102*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < pReleaseInfo->imageIndexCount; i++) {
1103*61046927SAndroid Build Coastguard Worker          uint32_t image_index = pReleaseInfo->pImageIndices[i];
1104*61046927SAndroid Build Coastguard Worker          VkDeviceMemory mem = swapchain->get_wsi_image(swapchain, image_index)->memory;
1105*61046927SAndroid Build Coastguard Worker          swapchain->wsi->set_memory_ownership(swapchain->device, mem, false);
1106*61046927SAndroid Build Coastguard Worker       }
1107*61046927SAndroid Build Coastguard Worker    }
1108*61046927SAndroid Build Coastguard Worker 
1109*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1110*61046927SAndroid Build Coastguard Worker }
1111*61046927SAndroid Build Coastguard Worker 
1112*61046927SAndroid Build Coastguard Worker VkResult
wsi_common_get_images(VkSwapchainKHR _swapchain,uint32_t * pSwapchainImageCount,VkImage * pSwapchainImages)1113*61046927SAndroid Build Coastguard Worker wsi_common_get_images(VkSwapchainKHR _swapchain,
1114*61046927SAndroid Build Coastguard Worker                       uint32_t *pSwapchainImageCount,
1115*61046927SAndroid Build Coastguard Worker                       VkImage *pSwapchainImages)
1116*61046927SAndroid Build Coastguard Worker {
1117*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain);
1118*61046927SAndroid Build Coastguard Worker    VK_OUTARRAY_MAKE_TYPED(VkImage, images, pSwapchainImages, pSwapchainImageCount);
1119*61046927SAndroid Build Coastguard Worker 
1120*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < swapchain->image_count; i++) {
1121*61046927SAndroid Build Coastguard Worker       vk_outarray_append_typed(VkImage, &images, image) {
1122*61046927SAndroid Build Coastguard Worker          *image = swapchain->get_wsi_image(swapchain, i)->image;
1123*61046927SAndroid Build Coastguard Worker       }
1124*61046927SAndroid Build Coastguard Worker    }
1125*61046927SAndroid Build Coastguard Worker 
1126*61046927SAndroid Build Coastguard Worker    return vk_outarray_status(&images);
1127*61046927SAndroid Build Coastguard Worker }
1128*61046927SAndroid Build Coastguard Worker 
1129*61046927SAndroid Build Coastguard Worker VkImage
wsi_common_get_image(VkSwapchainKHR _swapchain,uint32_t index)1130*61046927SAndroid Build Coastguard Worker wsi_common_get_image(VkSwapchainKHR _swapchain, uint32_t index)
1131*61046927SAndroid Build Coastguard Worker {
1132*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain);
1133*61046927SAndroid Build Coastguard Worker    assert(index < swapchain->image_count);
1134*61046927SAndroid Build Coastguard Worker    return swapchain->get_wsi_image(swapchain, index)->image;
1135*61046927SAndroid Build Coastguard Worker }
1136*61046927SAndroid Build Coastguard Worker 
1137*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
wsi_GetSwapchainImagesKHR(VkDevice device,VkSwapchainKHR swapchain,uint32_t * pSwapchainImageCount,VkImage * pSwapchainImages)1138*61046927SAndroid Build Coastguard Worker wsi_GetSwapchainImagesKHR(VkDevice device,
1139*61046927SAndroid Build Coastguard Worker                           VkSwapchainKHR swapchain,
1140*61046927SAndroid Build Coastguard Worker                           uint32_t *pSwapchainImageCount,
1141*61046927SAndroid Build Coastguard Worker                           VkImage *pSwapchainImages)
1142*61046927SAndroid Build Coastguard Worker {
1143*61046927SAndroid Build Coastguard Worker    MESA_TRACE_FUNC();
1144*61046927SAndroid Build Coastguard Worker    return wsi_common_get_images(swapchain,
1145*61046927SAndroid Build Coastguard Worker                                 pSwapchainImageCount,
1146*61046927SAndroid Build Coastguard Worker                                 pSwapchainImages);
1147*61046927SAndroid Build Coastguard Worker }
1148*61046927SAndroid Build Coastguard Worker 
1149*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
wsi_AcquireNextImageKHR(VkDevice _device,VkSwapchainKHR swapchain,uint64_t timeout,VkSemaphore semaphore,VkFence fence,uint32_t * pImageIndex)1150*61046927SAndroid Build Coastguard Worker wsi_AcquireNextImageKHR(VkDevice _device,
1151*61046927SAndroid Build Coastguard Worker                         VkSwapchainKHR swapchain,
1152*61046927SAndroid Build Coastguard Worker                         uint64_t timeout,
1153*61046927SAndroid Build Coastguard Worker                         VkSemaphore semaphore,
1154*61046927SAndroid Build Coastguard Worker                         VkFence fence,
1155*61046927SAndroid Build Coastguard Worker                         uint32_t *pImageIndex)
1156*61046927SAndroid Build Coastguard Worker {
1157*61046927SAndroid Build Coastguard Worker    MESA_TRACE_FUNC();
1158*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_device, device, _device);
1159*61046927SAndroid Build Coastguard Worker 
1160*61046927SAndroid Build Coastguard Worker    const VkAcquireNextImageInfoKHR acquire_info = {
1161*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR,
1162*61046927SAndroid Build Coastguard Worker       .swapchain = swapchain,
1163*61046927SAndroid Build Coastguard Worker       .timeout = timeout,
1164*61046927SAndroid Build Coastguard Worker       .semaphore = semaphore,
1165*61046927SAndroid Build Coastguard Worker       .fence = fence,
1166*61046927SAndroid Build Coastguard Worker       .deviceMask = 0,
1167*61046927SAndroid Build Coastguard Worker    };
1168*61046927SAndroid Build Coastguard Worker 
1169*61046927SAndroid Build Coastguard Worker    return device->dispatch_table.AcquireNextImage2KHR(_device, &acquire_info,
1170*61046927SAndroid Build Coastguard Worker                                                       pImageIndex);
1171*61046927SAndroid Build Coastguard Worker }
1172*61046927SAndroid Build Coastguard Worker 
1173*61046927SAndroid Build Coastguard Worker static VkResult
wsi_signal_semaphore_for_image(struct vk_device * device,const struct wsi_swapchain * chain,const struct wsi_image * image,VkSemaphore _semaphore)1174*61046927SAndroid Build Coastguard Worker wsi_signal_semaphore_for_image(struct vk_device *device,
1175*61046927SAndroid Build Coastguard Worker                                const struct wsi_swapchain *chain,
1176*61046927SAndroid Build Coastguard Worker                                const struct wsi_image *image,
1177*61046927SAndroid Build Coastguard Worker                                VkSemaphore _semaphore)
1178*61046927SAndroid Build Coastguard Worker {
1179*61046927SAndroid Build Coastguard Worker    if (device->physical->supported_sync_types == NULL)
1180*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
1181*61046927SAndroid Build Coastguard Worker 
1182*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_semaphore, semaphore, _semaphore);
1183*61046927SAndroid Build Coastguard Worker 
1184*61046927SAndroid Build Coastguard Worker    vk_semaphore_reset_temporary(device, semaphore);
1185*61046927SAndroid Build Coastguard Worker 
1186*61046927SAndroid Build Coastguard Worker #ifdef HAVE_LIBDRM
1187*61046927SAndroid Build Coastguard Worker    VkResult result = chain->image_info.explicit_sync ?
1188*61046927SAndroid Build Coastguard Worker       wsi_create_sync_for_image_syncobj(chain, image,
1189*61046927SAndroid Build Coastguard Worker                                         VK_SYNC_FEATURE_GPU_WAIT,
1190*61046927SAndroid Build Coastguard Worker                                         &semaphore->temporary) :
1191*61046927SAndroid Build Coastguard Worker       wsi_create_sync_for_dma_buf_wait(chain, image,
1192*61046927SAndroid Build Coastguard Worker                                        VK_SYNC_FEATURE_GPU_WAIT,
1193*61046927SAndroid Build Coastguard Worker                                        &semaphore->temporary);
1194*61046927SAndroid Build Coastguard Worker    if (result != VK_ERROR_FEATURE_NOT_PRESENT)
1195*61046927SAndroid Build Coastguard Worker       return result;
1196*61046927SAndroid Build Coastguard Worker #endif
1197*61046927SAndroid Build Coastguard Worker 
1198*61046927SAndroid Build Coastguard Worker    if (chain->wsi->signal_semaphore_with_memory) {
1199*61046927SAndroid Build Coastguard Worker       return device->create_sync_for_memory(device, image->memory,
1200*61046927SAndroid Build Coastguard Worker                                             false /* signal_memory */,
1201*61046927SAndroid Build Coastguard Worker                                             &semaphore->temporary);
1202*61046927SAndroid Build Coastguard Worker    } else {
1203*61046927SAndroid Build Coastguard Worker       return vk_sync_create(device, &vk_sync_dummy_type,
1204*61046927SAndroid Build Coastguard Worker                             0 /* flags */, 0 /* initial_value */,
1205*61046927SAndroid Build Coastguard Worker                             &semaphore->temporary);
1206*61046927SAndroid Build Coastguard Worker    }
1207*61046927SAndroid Build Coastguard Worker }
1208*61046927SAndroid Build Coastguard Worker 
1209*61046927SAndroid Build Coastguard Worker static VkResult
wsi_signal_fence_for_image(struct vk_device * device,const struct wsi_swapchain * chain,const struct wsi_image * image,VkFence _fence)1210*61046927SAndroid Build Coastguard Worker wsi_signal_fence_for_image(struct vk_device *device,
1211*61046927SAndroid Build Coastguard Worker                            const struct wsi_swapchain *chain,
1212*61046927SAndroid Build Coastguard Worker                            const struct wsi_image *image,
1213*61046927SAndroid Build Coastguard Worker                            VkFence _fence)
1214*61046927SAndroid Build Coastguard Worker {
1215*61046927SAndroid Build Coastguard Worker    if (device->physical->supported_sync_types == NULL)
1216*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
1217*61046927SAndroid Build Coastguard Worker 
1218*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_fence, fence, _fence);
1219*61046927SAndroid Build Coastguard Worker 
1220*61046927SAndroid Build Coastguard Worker    vk_fence_reset_temporary(device, fence);
1221*61046927SAndroid Build Coastguard Worker 
1222*61046927SAndroid Build Coastguard Worker #ifdef HAVE_LIBDRM
1223*61046927SAndroid Build Coastguard Worker    VkResult result = chain->image_info.explicit_sync ?
1224*61046927SAndroid Build Coastguard Worker       wsi_create_sync_for_image_syncobj(chain, image,
1225*61046927SAndroid Build Coastguard Worker                                         VK_SYNC_FEATURE_CPU_WAIT,
1226*61046927SAndroid Build Coastguard Worker                                         &fence->temporary) :
1227*61046927SAndroid Build Coastguard Worker       wsi_create_sync_for_dma_buf_wait(chain, image,
1228*61046927SAndroid Build Coastguard Worker                                        VK_SYNC_FEATURE_CPU_WAIT,
1229*61046927SAndroid Build Coastguard Worker                                        &fence->temporary);
1230*61046927SAndroid Build Coastguard Worker    if (result != VK_ERROR_FEATURE_NOT_PRESENT)
1231*61046927SAndroid Build Coastguard Worker       return result;
1232*61046927SAndroid Build Coastguard Worker #endif
1233*61046927SAndroid Build Coastguard Worker 
1234*61046927SAndroid Build Coastguard Worker    if (chain->wsi->signal_fence_with_memory) {
1235*61046927SAndroid Build Coastguard Worker       return device->create_sync_for_memory(device, image->memory,
1236*61046927SAndroid Build Coastguard Worker                                             false /* signal_memory */,
1237*61046927SAndroid Build Coastguard Worker                                             &fence->temporary);
1238*61046927SAndroid Build Coastguard Worker    } else {
1239*61046927SAndroid Build Coastguard Worker       return vk_sync_create(device, &vk_sync_dummy_type,
1240*61046927SAndroid Build Coastguard Worker                             0 /* flags */, 0 /* initial_value */,
1241*61046927SAndroid Build Coastguard Worker                             &fence->temporary);
1242*61046927SAndroid Build Coastguard Worker    }
1243*61046927SAndroid Build Coastguard Worker }
1244*61046927SAndroid Build Coastguard Worker 
1245*61046927SAndroid Build Coastguard Worker VkResult
wsi_common_acquire_next_image2(const struct wsi_device * wsi,VkDevice _device,const VkAcquireNextImageInfoKHR * pAcquireInfo,uint32_t * pImageIndex)1246*61046927SAndroid Build Coastguard Worker wsi_common_acquire_next_image2(const struct wsi_device *wsi,
1247*61046927SAndroid Build Coastguard Worker                                VkDevice _device,
1248*61046927SAndroid Build Coastguard Worker                                const VkAcquireNextImageInfoKHR *pAcquireInfo,
1249*61046927SAndroid Build Coastguard Worker                                uint32_t *pImageIndex)
1250*61046927SAndroid Build Coastguard Worker {
1251*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(wsi_swapchain, swapchain, pAcquireInfo->swapchain);
1252*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_device, device, _device);
1253*61046927SAndroid Build Coastguard Worker 
1254*61046927SAndroid Build Coastguard Worker    VkResult result = swapchain->acquire_next_image(swapchain, pAcquireInfo,
1255*61046927SAndroid Build Coastguard Worker                                                    pImageIndex);
1256*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)
1257*61046927SAndroid Build Coastguard Worker       return result;
1258*61046927SAndroid Build Coastguard Worker    struct wsi_image *image =
1259*61046927SAndroid Build Coastguard Worker       swapchain->get_wsi_image(swapchain, *pImageIndex);
1260*61046927SAndroid Build Coastguard Worker 
1261*61046927SAndroid Build Coastguard Worker    image->acquired = true;
1262*61046927SAndroid Build Coastguard Worker 
1263*61046927SAndroid Build Coastguard Worker    if (pAcquireInfo->semaphore != VK_NULL_HANDLE) {
1264*61046927SAndroid Build Coastguard Worker       VkResult signal_result =
1265*61046927SAndroid Build Coastguard Worker          wsi_signal_semaphore_for_image(device, swapchain, image,
1266*61046927SAndroid Build Coastguard Worker                                         pAcquireInfo->semaphore);
1267*61046927SAndroid Build Coastguard Worker       if (signal_result != VK_SUCCESS)
1268*61046927SAndroid Build Coastguard Worker          return signal_result;
1269*61046927SAndroid Build Coastguard Worker    }
1270*61046927SAndroid Build Coastguard Worker 
1271*61046927SAndroid Build Coastguard Worker    if (pAcquireInfo->fence != VK_NULL_HANDLE) {
1272*61046927SAndroid Build Coastguard Worker       VkResult signal_result =
1273*61046927SAndroid Build Coastguard Worker          wsi_signal_fence_for_image(device, swapchain, image,
1274*61046927SAndroid Build Coastguard Worker                                     pAcquireInfo->fence);
1275*61046927SAndroid Build Coastguard Worker       if (signal_result != VK_SUCCESS)
1276*61046927SAndroid Build Coastguard Worker          return signal_result;
1277*61046927SAndroid Build Coastguard Worker    }
1278*61046927SAndroid Build Coastguard Worker 
1279*61046927SAndroid Build Coastguard Worker    if (wsi->set_memory_ownership)
1280*61046927SAndroid Build Coastguard Worker       wsi->set_memory_ownership(swapchain->device, image->memory, true);
1281*61046927SAndroid Build Coastguard Worker 
1282*61046927SAndroid Build Coastguard Worker    return result;
1283*61046927SAndroid Build Coastguard Worker }
1284*61046927SAndroid Build Coastguard Worker 
1285*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
wsi_AcquireNextImage2KHR(VkDevice _device,const VkAcquireNextImageInfoKHR * pAcquireInfo,uint32_t * pImageIndex)1286*61046927SAndroid Build Coastguard Worker wsi_AcquireNextImage2KHR(VkDevice _device,
1287*61046927SAndroid Build Coastguard Worker                          const VkAcquireNextImageInfoKHR *pAcquireInfo,
1288*61046927SAndroid Build Coastguard Worker                          uint32_t *pImageIndex)
1289*61046927SAndroid Build Coastguard Worker {
1290*61046927SAndroid Build Coastguard Worker    MESA_TRACE_FUNC();
1291*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_device, device, _device);
1292*61046927SAndroid Build Coastguard Worker 
1293*61046927SAndroid Build Coastguard Worker    return wsi_common_acquire_next_image2(device->physical->wsi_device,
1294*61046927SAndroid Build Coastguard Worker                                          _device, pAcquireInfo, pImageIndex);
1295*61046927SAndroid Build Coastguard Worker }
1296*61046927SAndroid Build Coastguard Worker 
wsi_signal_present_id_timeline(struct wsi_swapchain * swapchain,VkQueue queue,uint64_t present_id,VkFence present_fence)1297*61046927SAndroid Build Coastguard Worker static VkResult wsi_signal_present_id_timeline(struct wsi_swapchain *swapchain,
1298*61046927SAndroid Build Coastguard Worker                                                VkQueue queue, uint64_t present_id,
1299*61046927SAndroid Build Coastguard Worker                                                VkFence present_fence)
1300*61046927SAndroid Build Coastguard Worker {
1301*61046927SAndroid Build Coastguard Worker    assert(swapchain->present_id_timeline || present_fence);
1302*61046927SAndroid Build Coastguard Worker 
1303*61046927SAndroid Build Coastguard Worker    const VkTimelineSemaphoreSubmitInfo timeline_info = {
1304*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
1305*61046927SAndroid Build Coastguard Worker       .pSignalSemaphoreValues = &present_id,
1306*61046927SAndroid Build Coastguard Worker       .signalSemaphoreValueCount = 1,
1307*61046927SAndroid Build Coastguard Worker    };
1308*61046927SAndroid Build Coastguard Worker 
1309*61046927SAndroid Build Coastguard Worker    const VkSubmitInfo submit_info = {
1310*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
1311*61046927SAndroid Build Coastguard Worker       .pNext = &timeline_info,
1312*61046927SAndroid Build Coastguard Worker       .signalSemaphoreCount = 1,
1313*61046927SAndroid Build Coastguard Worker       .pSignalSemaphores = &swapchain->present_id_timeline,
1314*61046927SAndroid Build Coastguard Worker    };
1315*61046927SAndroid Build Coastguard Worker 
1316*61046927SAndroid Build Coastguard Worker    uint32_t submit_count = present_id ? 1 : 0;
1317*61046927SAndroid Build Coastguard Worker    return swapchain->wsi->QueueSubmit(queue, submit_count, &submit_info, present_fence);
1318*61046927SAndroid Build Coastguard Worker }
1319*61046927SAndroid Build Coastguard Worker 
1320*61046927SAndroid Build Coastguard Worker static VkResult
handle_trace(VkQueue queue,struct vk_device * device,uint32_t current_frame)1321*61046927SAndroid Build Coastguard Worker handle_trace(VkQueue queue, struct vk_device *device, uint32_t current_frame)
1322*61046927SAndroid Build Coastguard Worker {
1323*61046927SAndroid Build Coastguard Worker    struct vk_instance *instance = device->physical->instance;
1324*61046927SAndroid Build Coastguard Worker    if (!instance->trace_mode)
1325*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
1326*61046927SAndroid Build Coastguard Worker 
1327*61046927SAndroid Build Coastguard Worker    simple_mtx_lock(&device->trace_mtx);
1328*61046927SAndroid Build Coastguard Worker 
1329*61046927SAndroid Build Coastguard Worker    bool frame_trigger = device->current_frame == instance->trace_frame;
1330*61046927SAndroid Build Coastguard Worker 
1331*61046927SAndroid Build Coastguard Worker    bool file_trigger = false;
1332*61046927SAndroid Build Coastguard Worker #ifndef _WIN32
1333*61046927SAndroid Build Coastguard Worker    if (instance->trace_trigger_file && access(instance->trace_trigger_file, W_OK) == 0) {
1334*61046927SAndroid Build Coastguard Worker       if (unlink(instance->trace_trigger_file) == 0) {
1335*61046927SAndroid Build Coastguard Worker          file_trigger = true;
1336*61046927SAndroid Build Coastguard Worker       } else {
1337*61046927SAndroid Build Coastguard Worker          /* Do not enable tracing if we cannot remove the file,
1338*61046927SAndroid Build Coastguard Worker           * because by then we'll trace every frame ... */
1339*61046927SAndroid Build Coastguard Worker          fprintf(stderr, "Could not remove trace trigger file, ignoring\n");
1340*61046927SAndroid Build Coastguard Worker       }
1341*61046927SAndroid Build Coastguard Worker    }
1342*61046927SAndroid Build Coastguard Worker #endif
1343*61046927SAndroid Build Coastguard Worker 
1344*61046927SAndroid Build Coastguard Worker    VkResult result = VK_SUCCESS;
1345*61046927SAndroid Build Coastguard Worker    if (frame_trigger || file_trigger || device->trace_hotkey_trigger)
1346*61046927SAndroid Build Coastguard Worker       result = device->capture_trace(queue);
1347*61046927SAndroid Build Coastguard Worker 
1348*61046927SAndroid Build Coastguard Worker    device->trace_hotkey_trigger = false;
1349*61046927SAndroid Build Coastguard Worker 
1350*61046927SAndroid Build Coastguard Worker    simple_mtx_unlock(&device->trace_mtx);
1351*61046927SAndroid Build Coastguard Worker 
1352*61046927SAndroid Build Coastguard Worker    return result;
1353*61046927SAndroid Build Coastguard Worker }
1354*61046927SAndroid Build Coastguard Worker 
1355*61046927SAndroid Build Coastguard Worker VkResult
wsi_common_queue_present(const struct wsi_device * wsi,VkDevice device,VkQueue queue,int queue_family_index,const VkPresentInfoKHR * pPresentInfo)1356*61046927SAndroid Build Coastguard Worker wsi_common_queue_present(const struct wsi_device *wsi,
1357*61046927SAndroid Build Coastguard Worker                          VkDevice device,
1358*61046927SAndroid Build Coastguard Worker                          VkQueue queue,
1359*61046927SAndroid Build Coastguard Worker                          int queue_family_index,
1360*61046927SAndroid Build Coastguard Worker                          const VkPresentInfoKHR *pPresentInfo)
1361*61046927SAndroid Build Coastguard Worker {
1362*61046927SAndroid Build Coastguard Worker    struct vk_device *dev = vk_device_from_handle(device);
1363*61046927SAndroid Build Coastguard Worker    uint32_t current_frame = p_atomic_fetch_add(&dev->current_frame, 1);
1364*61046927SAndroid Build Coastguard Worker    VkResult final_result = handle_trace(queue, dev, current_frame);
1365*61046927SAndroid Build Coastguard Worker 
1366*61046927SAndroid Build Coastguard Worker    STACK_ARRAY(VkPipelineStageFlags, stage_flags,
1367*61046927SAndroid Build Coastguard Worker                MAX2(1, pPresentInfo->waitSemaphoreCount));
1368*61046927SAndroid Build Coastguard Worker    for (uint32_t s = 0; s < MAX2(1, pPresentInfo->waitSemaphoreCount); s++)
1369*61046927SAndroid Build Coastguard Worker       stage_flags[s] = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1370*61046927SAndroid Build Coastguard Worker 
1371*61046927SAndroid Build Coastguard Worker    const VkPresentRegionsKHR *regions =
1372*61046927SAndroid Build Coastguard Worker       vk_find_struct_const(pPresentInfo->pNext, PRESENT_REGIONS_KHR);
1373*61046927SAndroid Build Coastguard Worker    const VkPresentIdKHR *present_ids =
1374*61046927SAndroid Build Coastguard Worker       vk_find_struct_const(pPresentInfo->pNext, PRESENT_ID_KHR);
1375*61046927SAndroid Build Coastguard Worker    const VkSwapchainPresentFenceInfoEXT *present_fence_info =
1376*61046927SAndroid Build Coastguard Worker       vk_find_struct_const(pPresentInfo->pNext, SWAPCHAIN_PRESENT_FENCE_INFO_EXT);
1377*61046927SAndroid Build Coastguard Worker    const VkSwapchainPresentModeInfoEXT *present_mode_info =
1378*61046927SAndroid Build Coastguard Worker       vk_find_struct_const(pPresentInfo->pNext, SWAPCHAIN_PRESENT_MODE_INFO_EXT);
1379*61046927SAndroid Build Coastguard Worker 
1380*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < pPresentInfo->swapchainCount; i++) {
1381*61046927SAndroid Build Coastguard Worker       VK_FROM_HANDLE(wsi_swapchain, swapchain, pPresentInfo->pSwapchains[i]);
1382*61046927SAndroid Build Coastguard Worker       uint32_t image_index = pPresentInfo->pImageIndices[i];
1383*61046927SAndroid Build Coastguard Worker       VkResult result;
1384*61046927SAndroid Build Coastguard Worker 
1385*61046927SAndroid Build Coastguard Worker       /* Update the present mode for this present and any subsequent present.
1386*61046927SAndroid Build Coastguard Worker        * Only update the present mode when MESA_VK_WSI_PRESENT_MODE is not used.
1387*61046927SAndroid Build Coastguard Worker        * We should also turn any VkSwapchainPresentModesCreateInfoEXT into a nop,
1388*61046927SAndroid Build Coastguard Worker        * but none of the WSI backends use that currently. */
1389*61046927SAndroid Build Coastguard Worker       if (present_mode_info && present_mode_info->pPresentModes &&
1390*61046927SAndroid Build Coastguard Worker           swapchain->set_present_mode && wsi->override_present_mode == VK_PRESENT_MODE_MAX_ENUM_KHR) {
1391*61046927SAndroid Build Coastguard Worker          swapchain->set_present_mode(swapchain, present_mode_info->pPresentModes[i]);
1392*61046927SAndroid Build Coastguard Worker       }
1393*61046927SAndroid Build Coastguard Worker 
1394*61046927SAndroid Build Coastguard Worker       if (swapchain->fences[image_index] == VK_NULL_HANDLE) {
1395*61046927SAndroid Build Coastguard Worker          const VkFenceCreateInfo fence_info = {
1396*61046927SAndroid Build Coastguard Worker             .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1397*61046927SAndroid Build Coastguard Worker             .pNext = NULL,
1398*61046927SAndroid Build Coastguard Worker             .flags = VK_FENCE_CREATE_SIGNALED_BIT,
1399*61046927SAndroid Build Coastguard Worker          };
1400*61046927SAndroid Build Coastguard Worker          result = wsi->CreateFence(device, &fence_info,
1401*61046927SAndroid Build Coastguard Worker                                    &swapchain->alloc,
1402*61046927SAndroid Build Coastguard Worker                                    &swapchain->fences[image_index]);
1403*61046927SAndroid Build Coastguard Worker          if (result != VK_SUCCESS)
1404*61046927SAndroid Build Coastguard Worker             goto fail_present;
1405*61046927SAndroid Build Coastguard Worker 
1406*61046927SAndroid Build Coastguard Worker          if (swapchain->blit.type != WSI_SWAPCHAIN_NO_BLIT &&
1407*61046927SAndroid Build Coastguard Worker              swapchain->blit.queue != VK_NULL_HANDLE) {
1408*61046927SAndroid Build Coastguard Worker             const VkSemaphoreCreateInfo sem_info = {
1409*61046927SAndroid Build Coastguard Worker                .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
1410*61046927SAndroid Build Coastguard Worker                .pNext = NULL,
1411*61046927SAndroid Build Coastguard Worker                .flags = 0,
1412*61046927SAndroid Build Coastguard Worker             };
1413*61046927SAndroid Build Coastguard Worker             result = wsi->CreateSemaphore(device, &sem_info,
1414*61046927SAndroid Build Coastguard Worker                                           &swapchain->alloc,
1415*61046927SAndroid Build Coastguard Worker                                           &swapchain->blit.semaphores[image_index]);
1416*61046927SAndroid Build Coastguard Worker             if (result != VK_SUCCESS)
1417*61046927SAndroid Build Coastguard Worker                goto fail_present;
1418*61046927SAndroid Build Coastguard Worker          }
1419*61046927SAndroid Build Coastguard Worker       } else {
1420*61046927SAndroid Build Coastguard Worker          MESA_TRACE_SCOPE("throttle");
1421*61046927SAndroid Build Coastguard Worker          result =
1422*61046927SAndroid Build Coastguard Worker             wsi->WaitForFences(device, 1, &swapchain->fences[image_index],
1423*61046927SAndroid Build Coastguard Worker                                true, ~0ull);
1424*61046927SAndroid Build Coastguard Worker          if (result != VK_SUCCESS)
1425*61046927SAndroid Build Coastguard Worker             goto fail_present;
1426*61046927SAndroid Build Coastguard Worker       }
1427*61046927SAndroid Build Coastguard Worker 
1428*61046927SAndroid Build Coastguard Worker       result = wsi->ResetFences(device, 1, &swapchain->fences[image_index]);
1429*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
1430*61046927SAndroid Build Coastguard Worker          goto fail_present;
1431*61046927SAndroid Build Coastguard Worker 
1432*61046927SAndroid Build Coastguard Worker       VkTimelineSemaphoreSubmitInfo timeline_submit_info = {
1433*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
1434*61046927SAndroid Build Coastguard Worker       };
1435*61046927SAndroid Build Coastguard Worker 
1436*61046927SAndroid Build Coastguard Worker       VkSubmitInfo submit_info = {
1437*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
1438*61046927SAndroid Build Coastguard Worker       };
1439*61046927SAndroid Build Coastguard Worker 
1440*61046927SAndroid Build Coastguard Worker       if (i == 0) {
1441*61046927SAndroid Build Coastguard Worker          /* We only need/want to wait on semaphores once.  After that, we're
1442*61046927SAndroid Build Coastguard Worker           * guaranteed ordering since it all happens on the same queue.
1443*61046927SAndroid Build Coastguard Worker           */
1444*61046927SAndroid Build Coastguard Worker          submit_info.waitSemaphoreCount = pPresentInfo->waitSemaphoreCount;
1445*61046927SAndroid Build Coastguard Worker          submit_info.pWaitSemaphores = pPresentInfo->pWaitSemaphores;
1446*61046927SAndroid Build Coastguard Worker          submit_info.pWaitDstStageMask = stage_flags;
1447*61046927SAndroid Build Coastguard Worker       }
1448*61046927SAndroid Build Coastguard Worker 
1449*61046927SAndroid Build Coastguard Worker       struct wsi_image *image =
1450*61046927SAndroid Build Coastguard Worker          swapchain->get_wsi_image(swapchain, image_index);
1451*61046927SAndroid Build Coastguard Worker 
1452*61046927SAndroid Build Coastguard Worker       VkQueue submit_queue = queue;
1453*61046927SAndroid Build Coastguard Worker       if (swapchain->blit.type != WSI_SWAPCHAIN_NO_BLIT) {
1454*61046927SAndroid Build Coastguard Worker          if (swapchain->blit.queue == VK_NULL_HANDLE) {
1455*61046927SAndroid Build Coastguard Worker             submit_info.commandBufferCount = 1;
1456*61046927SAndroid Build Coastguard Worker             submit_info.pCommandBuffers =
1457*61046927SAndroid Build Coastguard Worker                &image->blit.cmd_buffers[queue_family_index];
1458*61046927SAndroid Build Coastguard Worker          } else {
1459*61046927SAndroid Build Coastguard Worker             /* If we are using a blit using the driver's private queue, then
1460*61046927SAndroid Build Coastguard Worker              * do an empty submit signalling a semaphore, and then submit the
1461*61046927SAndroid Build Coastguard Worker              * blit waiting on that.  This ensures proper queue ordering of
1462*61046927SAndroid Build Coastguard Worker              * vkQueueSubmit() calls.
1463*61046927SAndroid Build Coastguard Worker              */
1464*61046927SAndroid Build Coastguard Worker             submit_info.signalSemaphoreCount = 1;
1465*61046927SAndroid Build Coastguard Worker             submit_info.pSignalSemaphores =
1466*61046927SAndroid Build Coastguard Worker                &swapchain->blit.semaphores[image_index];
1467*61046927SAndroid Build Coastguard Worker 
1468*61046927SAndroid Build Coastguard Worker             result = wsi->QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
1469*61046927SAndroid Build Coastguard Worker             if (result != VK_SUCCESS)
1470*61046927SAndroid Build Coastguard Worker                goto fail_present;
1471*61046927SAndroid Build Coastguard Worker 
1472*61046927SAndroid Build Coastguard Worker             /* Now prepare the blit submit.  It needs to then wait on the
1473*61046927SAndroid Build Coastguard Worker              * semaphore we signaled above.
1474*61046927SAndroid Build Coastguard Worker              */
1475*61046927SAndroid Build Coastguard Worker             submit_queue = swapchain->blit.queue;
1476*61046927SAndroid Build Coastguard Worker             submit_info.waitSemaphoreCount = 1;
1477*61046927SAndroid Build Coastguard Worker             submit_info.pWaitSemaphores = submit_info.pSignalSemaphores;
1478*61046927SAndroid Build Coastguard Worker             submit_info.signalSemaphoreCount = 0;
1479*61046927SAndroid Build Coastguard Worker             submit_info.pSignalSemaphores = NULL;
1480*61046927SAndroid Build Coastguard Worker             submit_info.commandBufferCount = 1;
1481*61046927SAndroid Build Coastguard Worker             submit_info.pCommandBuffers = &image->blit.cmd_buffers[0];
1482*61046927SAndroid Build Coastguard Worker             submit_info.pWaitDstStageMask = stage_flags;
1483*61046927SAndroid Build Coastguard Worker          }
1484*61046927SAndroid Build Coastguard Worker       }
1485*61046927SAndroid Build Coastguard Worker 
1486*61046927SAndroid Build Coastguard Worker       VkFence fence = swapchain->fences[image_index];
1487*61046927SAndroid Build Coastguard Worker 
1488*61046927SAndroid Build Coastguard Worker       struct wsi_memory_signal_submit_info mem_signal;
1489*61046927SAndroid Build Coastguard Worker       bool has_signal_dma_buf = false;
1490*61046927SAndroid Build Coastguard Worker       bool explicit_sync = swapchain->image_info.explicit_sync;
1491*61046927SAndroid Build Coastguard Worker       if (explicit_sync) {
1492*61046927SAndroid Build Coastguard Worker          /* We will signal this acquire value ourselves when GPU work is done. */
1493*61046927SAndroid Build Coastguard Worker          image->explicit_sync[WSI_ES_ACQUIRE].timeline++;
1494*61046927SAndroid Build Coastguard Worker          /* The compositor will signal this value when it is done with the image. */
1495*61046927SAndroid Build Coastguard Worker          image->explicit_sync[WSI_ES_RELEASE].timeline++;
1496*61046927SAndroid Build Coastguard Worker 
1497*61046927SAndroid Build Coastguard Worker          timeline_submit_info.signalSemaphoreValueCount = 1;
1498*61046927SAndroid Build Coastguard Worker          timeline_submit_info.pSignalSemaphoreValues = &image->explicit_sync[WSI_ES_ACQUIRE].timeline;
1499*61046927SAndroid Build Coastguard Worker 
1500*61046927SAndroid Build Coastguard Worker          assert(submit_info.signalSemaphoreCount == 0);
1501*61046927SAndroid Build Coastguard Worker          submit_info.signalSemaphoreCount = 1;
1502*61046927SAndroid Build Coastguard Worker          submit_info.pSignalSemaphores = &image->explicit_sync[WSI_ES_ACQUIRE].semaphore;
1503*61046927SAndroid Build Coastguard Worker          __vk_append_struct(&submit_info, &timeline_submit_info);
1504*61046927SAndroid Build Coastguard Worker       } else {
1505*61046927SAndroid Build Coastguard Worker #ifdef HAVE_LIBDRM
1506*61046927SAndroid Build Coastguard Worker          result = wsi_prepare_signal_dma_buf_from_semaphore(swapchain, image);
1507*61046927SAndroid Build Coastguard Worker          if (result == VK_SUCCESS) {
1508*61046927SAndroid Build Coastguard Worker             assert(submit_info.signalSemaphoreCount == 0);
1509*61046927SAndroid Build Coastguard Worker             submit_info.signalSemaphoreCount = 1;
1510*61046927SAndroid Build Coastguard Worker             submit_info.pSignalSemaphores = &swapchain->dma_buf_semaphore;
1511*61046927SAndroid Build Coastguard Worker             has_signal_dma_buf = true;
1512*61046927SAndroid Build Coastguard Worker          } else if (result == VK_ERROR_FEATURE_NOT_PRESENT) {
1513*61046927SAndroid Build Coastguard Worker             result = VK_SUCCESS;
1514*61046927SAndroid Build Coastguard Worker             has_signal_dma_buf = false;
1515*61046927SAndroid Build Coastguard Worker          } else {
1516*61046927SAndroid Build Coastguard Worker             goto fail_present;
1517*61046927SAndroid Build Coastguard Worker          }
1518*61046927SAndroid Build Coastguard Worker #endif
1519*61046927SAndroid Build Coastguard Worker 
1520*61046927SAndroid Build Coastguard Worker          if (!has_signal_dma_buf) {
1521*61046927SAndroid Build Coastguard Worker             /* If we don't have dma-buf signaling, signal the memory object by
1522*61046927SAndroid Build Coastguard Worker             * chaining wsi_memory_signal_submit_info into VkSubmitInfo.
1523*61046927SAndroid Build Coastguard Worker             */
1524*61046927SAndroid Build Coastguard Worker             result = VK_SUCCESS;
1525*61046927SAndroid Build Coastguard Worker             has_signal_dma_buf = false;
1526*61046927SAndroid Build Coastguard Worker             mem_signal = (struct wsi_memory_signal_submit_info) {
1527*61046927SAndroid Build Coastguard Worker                .sType = VK_STRUCTURE_TYPE_WSI_MEMORY_SIGNAL_SUBMIT_INFO_MESA,
1528*61046927SAndroid Build Coastguard Worker                .memory = image->memory,
1529*61046927SAndroid Build Coastguard Worker             };
1530*61046927SAndroid Build Coastguard Worker             __vk_append_struct(&submit_info, &mem_signal);
1531*61046927SAndroid Build Coastguard Worker          }
1532*61046927SAndroid Build Coastguard Worker       }
1533*61046927SAndroid Build Coastguard Worker 
1534*61046927SAndroid Build Coastguard Worker       result = wsi->QueueSubmit(submit_queue, 1, &submit_info, fence);
1535*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
1536*61046927SAndroid Build Coastguard Worker          goto fail_present;
1537*61046927SAndroid Build Coastguard Worker 
1538*61046927SAndroid Build Coastguard Worker       /* The app can only submit images they have acquired. */
1539*61046927SAndroid Build Coastguard Worker       assert(image->acquired);
1540*61046927SAndroid Build Coastguard Worker       image->acquired = false;
1541*61046927SAndroid Build Coastguard Worker       image->present_serial = ++swapchain->present_serial;
1542*61046927SAndroid Build Coastguard Worker 
1543*61046927SAndroid Build Coastguard Worker       if (!explicit_sync) {
1544*61046927SAndroid Build Coastguard Worker #ifdef HAVE_LIBDRM
1545*61046927SAndroid Build Coastguard Worker          if (has_signal_dma_buf) {
1546*61046927SAndroid Build Coastguard Worker             result = wsi_signal_dma_buf_from_semaphore(swapchain, image);
1547*61046927SAndroid Build Coastguard Worker             if (result != VK_SUCCESS)
1548*61046927SAndroid Build Coastguard Worker                goto fail_present;
1549*61046927SAndroid Build Coastguard Worker          }
1550*61046927SAndroid Build Coastguard Worker #else
1551*61046927SAndroid Build Coastguard Worker          assert(!has_signal_dma_buf);
1552*61046927SAndroid Build Coastguard Worker #endif
1553*61046927SAndroid Build Coastguard Worker       }
1554*61046927SAndroid Build Coastguard Worker 
1555*61046927SAndroid Build Coastguard Worker       if (wsi->sw)
1556*61046927SAndroid Build Coastguard Worker 	      wsi->WaitForFences(device, 1, &swapchain->fences[image_index],
1557*61046927SAndroid Build Coastguard Worker 				 true, ~0ull);
1558*61046927SAndroid Build Coastguard Worker 
1559*61046927SAndroid Build Coastguard Worker       const VkPresentRegionKHR *region = NULL;
1560*61046927SAndroid Build Coastguard Worker       if (regions && regions->pRegions)
1561*61046927SAndroid Build Coastguard Worker          region = &regions->pRegions[i];
1562*61046927SAndroid Build Coastguard Worker 
1563*61046927SAndroid Build Coastguard Worker       uint64_t present_id = 0;
1564*61046927SAndroid Build Coastguard Worker       if (present_ids && present_ids->pPresentIds)
1565*61046927SAndroid Build Coastguard Worker          present_id = present_ids->pPresentIds[i];
1566*61046927SAndroid Build Coastguard Worker       VkFence present_fence = VK_NULL_HANDLE;
1567*61046927SAndroid Build Coastguard Worker       if (present_fence_info && present_fence_info->pFences)
1568*61046927SAndroid Build Coastguard Worker          present_fence = present_fence_info->pFences[i];
1569*61046927SAndroid Build Coastguard Worker 
1570*61046927SAndroid Build Coastguard Worker       if (present_id || present_fence) {
1571*61046927SAndroid Build Coastguard Worker          result = wsi_signal_present_id_timeline(swapchain, queue, present_id, present_fence);
1572*61046927SAndroid Build Coastguard Worker          if (result != VK_SUCCESS)
1573*61046927SAndroid Build Coastguard Worker             goto fail_present;
1574*61046927SAndroid Build Coastguard Worker       }
1575*61046927SAndroid Build Coastguard Worker 
1576*61046927SAndroid Build Coastguard Worker       result = swapchain->queue_present(swapchain, image_index, present_id, region);
1577*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)
1578*61046927SAndroid Build Coastguard Worker          goto fail_present;
1579*61046927SAndroid Build Coastguard Worker 
1580*61046927SAndroid Build Coastguard Worker       if (wsi->set_memory_ownership) {
1581*61046927SAndroid Build Coastguard Worker          VkDeviceMemory mem = swapchain->get_wsi_image(swapchain, image_index)->memory;
1582*61046927SAndroid Build Coastguard Worker          wsi->set_memory_ownership(swapchain->device, mem, false);
1583*61046927SAndroid Build Coastguard Worker       }
1584*61046927SAndroid Build Coastguard Worker 
1585*61046927SAndroid Build Coastguard Worker    fail_present:
1586*61046927SAndroid Build Coastguard Worker       if (pPresentInfo->pResults != NULL)
1587*61046927SAndroid Build Coastguard Worker          pPresentInfo->pResults[i] = result;
1588*61046927SAndroid Build Coastguard Worker 
1589*61046927SAndroid Build Coastguard Worker       /* Let the final result be our first unsuccessful result */
1590*61046927SAndroid Build Coastguard Worker       if (final_result == VK_SUCCESS)
1591*61046927SAndroid Build Coastguard Worker          final_result = result;
1592*61046927SAndroid Build Coastguard Worker    }
1593*61046927SAndroid Build Coastguard Worker 
1594*61046927SAndroid Build Coastguard Worker    STACK_ARRAY_FINISH(stage_flags);
1595*61046927SAndroid Build Coastguard Worker 
1596*61046927SAndroid Build Coastguard Worker    return final_result;
1597*61046927SAndroid Build Coastguard Worker }
1598*61046927SAndroid Build Coastguard Worker 
1599*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
wsi_QueuePresentKHR(VkQueue _queue,const VkPresentInfoKHR * pPresentInfo)1600*61046927SAndroid Build Coastguard Worker wsi_QueuePresentKHR(VkQueue _queue, const VkPresentInfoKHR *pPresentInfo)
1601*61046927SAndroid Build Coastguard Worker {
1602*61046927SAndroid Build Coastguard Worker    MESA_TRACE_FUNC();
1603*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_queue, queue, _queue);
1604*61046927SAndroid Build Coastguard Worker 
1605*61046927SAndroid Build Coastguard Worker    return wsi_common_queue_present(queue->base.device->physical->wsi_device,
1606*61046927SAndroid Build Coastguard Worker                                    vk_device_to_handle(queue->base.device),
1607*61046927SAndroid Build Coastguard Worker                                    _queue,
1608*61046927SAndroid Build Coastguard Worker                                    queue->queue_family_index,
1609*61046927SAndroid Build Coastguard Worker                                    pPresentInfo);
1610*61046927SAndroid Build Coastguard Worker }
1611*61046927SAndroid Build Coastguard Worker 
1612*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
wsi_GetDeviceGroupPresentCapabilitiesKHR(VkDevice device,VkDeviceGroupPresentCapabilitiesKHR * pCapabilities)1613*61046927SAndroid Build Coastguard Worker wsi_GetDeviceGroupPresentCapabilitiesKHR(VkDevice device,
1614*61046927SAndroid Build Coastguard Worker                                          VkDeviceGroupPresentCapabilitiesKHR *pCapabilities)
1615*61046927SAndroid Build Coastguard Worker {
1616*61046927SAndroid Build Coastguard Worker    memset(pCapabilities->presentMask, 0,
1617*61046927SAndroid Build Coastguard Worker           sizeof(pCapabilities->presentMask));
1618*61046927SAndroid Build Coastguard Worker    pCapabilities->presentMask[0] = 0x1;
1619*61046927SAndroid Build Coastguard Worker    pCapabilities->modes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
1620*61046927SAndroid Build Coastguard Worker 
1621*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1622*61046927SAndroid Build Coastguard Worker }
1623*61046927SAndroid Build Coastguard Worker 
1624*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
wsi_GetDeviceGroupSurfacePresentModesKHR(VkDevice device,VkSurfaceKHR surface,VkDeviceGroupPresentModeFlagsKHR * pModes)1625*61046927SAndroid Build Coastguard Worker wsi_GetDeviceGroupSurfacePresentModesKHR(VkDevice device,
1626*61046927SAndroid Build Coastguard Worker                                          VkSurfaceKHR surface,
1627*61046927SAndroid Build Coastguard Worker                                          VkDeviceGroupPresentModeFlagsKHR *pModes)
1628*61046927SAndroid Build Coastguard Worker {
1629*61046927SAndroid Build Coastguard Worker    *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
1630*61046927SAndroid Build Coastguard Worker 
1631*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1632*61046927SAndroid Build Coastguard Worker }
1633*61046927SAndroid Build Coastguard Worker 
1634*61046927SAndroid Build Coastguard Worker bool
wsi_common_vk_instance_supports_present_wait(const struct vk_instance * instance)1635*61046927SAndroid Build Coastguard Worker wsi_common_vk_instance_supports_present_wait(const struct vk_instance *instance)
1636*61046927SAndroid Build Coastguard Worker {
1637*61046927SAndroid Build Coastguard Worker    /* We can only expose KHR_present_wait and KHR_present_id
1638*61046927SAndroid Build Coastguard Worker     * if we are guaranteed support on all potential VkSurfaceKHR objects. */
1639*61046927SAndroid Build Coastguard Worker    if (instance->enabled_extensions.KHR_win32_surface ||
1640*61046927SAndroid Build Coastguard Worker        instance->enabled_extensions.KHR_android_surface) {
1641*61046927SAndroid Build Coastguard Worker       return false;
1642*61046927SAndroid Build Coastguard Worker    }
1643*61046927SAndroid Build Coastguard Worker 
1644*61046927SAndroid Build Coastguard Worker    return true;
1645*61046927SAndroid Build Coastguard Worker }
1646*61046927SAndroid Build Coastguard Worker 
1647*61046927SAndroid Build Coastguard Worker VkResult
wsi_common_create_swapchain_image(const struct wsi_device * wsi,const VkImageCreateInfo * pCreateInfo,VkSwapchainKHR _swapchain,VkImage * pImage)1648*61046927SAndroid Build Coastguard Worker wsi_common_create_swapchain_image(const struct wsi_device *wsi,
1649*61046927SAndroid Build Coastguard Worker                                   const VkImageCreateInfo *pCreateInfo,
1650*61046927SAndroid Build Coastguard Worker                                   VkSwapchainKHR _swapchain,
1651*61046927SAndroid Build Coastguard Worker                                   VkImage *pImage)
1652*61046927SAndroid Build Coastguard Worker {
1653*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(wsi_swapchain, chain, _swapchain);
1654*61046927SAndroid Build Coastguard Worker 
1655*61046927SAndroid Build Coastguard Worker #ifndef NDEBUG
1656*61046927SAndroid Build Coastguard Worker    const VkImageCreateInfo *swcInfo = &chain->image_info.create;
1657*61046927SAndroid Build Coastguard Worker    assert(pCreateInfo->flags == 0);
1658*61046927SAndroid Build Coastguard Worker    assert(pCreateInfo->imageType == swcInfo->imageType);
1659*61046927SAndroid Build Coastguard Worker    assert(pCreateInfo->format == swcInfo->format);
1660*61046927SAndroid Build Coastguard Worker    assert(pCreateInfo->extent.width == swcInfo->extent.width);
1661*61046927SAndroid Build Coastguard Worker    assert(pCreateInfo->extent.height == swcInfo->extent.height);
1662*61046927SAndroid Build Coastguard Worker    assert(pCreateInfo->extent.depth == swcInfo->extent.depth);
1663*61046927SAndroid Build Coastguard Worker    assert(pCreateInfo->mipLevels == swcInfo->mipLevels);
1664*61046927SAndroid Build Coastguard Worker    assert(pCreateInfo->arrayLayers == swcInfo->arrayLayers);
1665*61046927SAndroid Build Coastguard Worker    assert(pCreateInfo->samples == swcInfo->samples);
1666*61046927SAndroid Build Coastguard Worker    assert(pCreateInfo->tiling == VK_IMAGE_TILING_OPTIMAL);
1667*61046927SAndroid Build Coastguard Worker    assert(!(pCreateInfo->usage & ~swcInfo->usage));
1668*61046927SAndroid Build Coastguard Worker 
1669*61046927SAndroid Build Coastguard Worker    vk_foreach_struct_const(ext, pCreateInfo->pNext) {
1670*61046927SAndroid Build Coastguard Worker       switch (ext->sType) {
1671*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO: {
1672*61046927SAndroid Build Coastguard Worker          const VkImageFormatListCreateInfo *iflci =
1673*61046927SAndroid Build Coastguard Worker             (const VkImageFormatListCreateInfo *)ext;
1674*61046927SAndroid Build Coastguard Worker          const VkImageFormatListCreateInfo *swc_iflci =
1675*61046927SAndroid Build Coastguard Worker             &chain->image_info.format_list;
1676*61046927SAndroid Build Coastguard Worker 
1677*61046927SAndroid Build Coastguard Worker          for (uint32_t i = 0; i < iflci->viewFormatCount; i++) {
1678*61046927SAndroid Build Coastguard Worker             bool found = false;
1679*61046927SAndroid Build Coastguard Worker             for (uint32_t j = 0; j < swc_iflci->viewFormatCount; j++) {
1680*61046927SAndroid Build Coastguard Worker                if (iflci->pViewFormats[i] == swc_iflci->pViewFormats[j]) {
1681*61046927SAndroid Build Coastguard Worker                   found = true;
1682*61046927SAndroid Build Coastguard Worker                   break;
1683*61046927SAndroid Build Coastguard Worker                }
1684*61046927SAndroid Build Coastguard Worker             }
1685*61046927SAndroid Build Coastguard Worker             assert(found);
1686*61046927SAndroid Build Coastguard Worker          }
1687*61046927SAndroid Build Coastguard Worker          break;
1688*61046927SAndroid Build Coastguard Worker       }
1689*61046927SAndroid Build Coastguard Worker 
1690*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR:
1691*61046927SAndroid Build Coastguard Worker          break;
1692*61046927SAndroid Build Coastguard Worker 
1693*61046927SAndroid Build Coastguard Worker       default:
1694*61046927SAndroid Build Coastguard Worker          assert(!"Unsupported image create extension");
1695*61046927SAndroid Build Coastguard Worker       }
1696*61046927SAndroid Build Coastguard Worker    }
1697*61046927SAndroid Build Coastguard Worker #endif
1698*61046927SAndroid Build Coastguard Worker 
1699*61046927SAndroid Build Coastguard Worker    return wsi->CreateImage(chain->device, &chain->image_info.create,
1700*61046927SAndroid Build Coastguard Worker                            &chain->alloc, pImage);
1701*61046927SAndroid Build Coastguard Worker }
1702*61046927SAndroid Build Coastguard Worker 
1703*61046927SAndroid Build Coastguard Worker VkResult
wsi_common_bind_swapchain_image(const struct wsi_device * wsi,VkImage vk_image,VkSwapchainKHR _swapchain,uint32_t image_idx)1704*61046927SAndroid Build Coastguard Worker wsi_common_bind_swapchain_image(const struct wsi_device *wsi,
1705*61046927SAndroid Build Coastguard Worker                                 VkImage vk_image,
1706*61046927SAndroid Build Coastguard Worker                                 VkSwapchainKHR _swapchain,
1707*61046927SAndroid Build Coastguard Worker                                 uint32_t image_idx)
1708*61046927SAndroid Build Coastguard Worker {
1709*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(wsi_swapchain, chain, _swapchain);
1710*61046927SAndroid Build Coastguard Worker    struct wsi_image *image = chain->get_wsi_image(chain, image_idx);
1711*61046927SAndroid Build Coastguard Worker 
1712*61046927SAndroid Build Coastguard Worker    return wsi->BindImageMemory(chain->device, vk_image, image->memory, 0);
1713*61046927SAndroid Build Coastguard Worker }
1714*61046927SAndroid Build Coastguard Worker 
1715*61046927SAndroid Build Coastguard Worker VkResult
wsi_swapchain_wait_for_present_semaphore(const struct wsi_swapchain * chain,uint64_t present_id,uint64_t timeout)1716*61046927SAndroid Build Coastguard Worker wsi_swapchain_wait_for_present_semaphore(const struct wsi_swapchain *chain,
1717*61046927SAndroid Build Coastguard Worker                                          uint64_t present_id, uint64_t timeout)
1718*61046927SAndroid Build Coastguard Worker {
1719*61046927SAndroid Build Coastguard Worker    assert(chain->present_id_timeline);
1720*61046927SAndroid Build Coastguard Worker    const VkSemaphoreWaitInfo wait_info = {
1721*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
1722*61046927SAndroid Build Coastguard Worker       .semaphoreCount = 1,
1723*61046927SAndroid Build Coastguard Worker       .pSemaphores = &chain->present_id_timeline,
1724*61046927SAndroid Build Coastguard Worker       .pValues = &present_id,
1725*61046927SAndroid Build Coastguard Worker    };
1726*61046927SAndroid Build Coastguard Worker 
1727*61046927SAndroid Build Coastguard Worker    return chain->wsi->WaitSemaphores(chain->device, &wait_info, timeout);
1728*61046927SAndroid Build Coastguard Worker }
1729*61046927SAndroid Build Coastguard Worker 
1730*61046927SAndroid Build Coastguard Worker uint32_t
wsi_select_memory_type(const struct wsi_device * wsi,VkMemoryPropertyFlags req_props,VkMemoryPropertyFlags deny_props,uint32_t type_bits)1731*61046927SAndroid Build Coastguard Worker wsi_select_memory_type(const struct wsi_device *wsi,
1732*61046927SAndroid Build Coastguard Worker                        VkMemoryPropertyFlags req_props,
1733*61046927SAndroid Build Coastguard Worker                        VkMemoryPropertyFlags deny_props,
1734*61046927SAndroid Build Coastguard Worker                        uint32_t type_bits)
1735*61046927SAndroid Build Coastguard Worker {
1736*61046927SAndroid Build Coastguard Worker    assert(type_bits != 0);
1737*61046927SAndroid Build Coastguard Worker 
1738*61046927SAndroid Build Coastguard Worker    VkMemoryPropertyFlags common_props = ~0;
1739*61046927SAndroid Build Coastguard Worker    u_foreach_bit(t, type_bits) {
1740*61046927SAndroid Build Coastguard Worker       const VkMemoryType type = wsi->memory_props.memoryTypes[t];
1741*61046927SAndroid Build Coastguard Worker 
1742*61046927SAndroid Build Coastguard Worker       common_props &= type.propertyFlags;
1743*61046927SAndroid Build Coastguard Worker 
1744*61046927SAndroid Build Coastguard Worker       if (deny_props & type.propertyFlags)
1745*61046927SAndroid Build Coastguard Worker          continue;
1746*61046927SAndroid Build Coastguard Worker 
1747*61046927SAndroid Build Coastguard Worker       if (!(req_props & ~type.propertyFlags))
1748*61046927SAndroid Build Coastguard Worker          return t;
1749*61046927SAndroid Build Coastguard Worker    }
1750*61046927SAndroid Build Coastguard Worker 
1751*61046927SAndroid Build Coastguard Worker    if ((deny_props & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) &&
1752*61046927SAndroid Build Coastguard Worker        (common_props & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
1753*61046927SAndroid Build Coastguard Worker       /* If they asked for non-device-local and all the types are device-local
1754*61046927SAndroid Build Coastguard Worker        * (this is commonly true for UMA platforms), try again without denying
1755*61046927SAndroid Build Coastguard Worker        * device-local types
1756*61046927SAndroid Build Coastguard Worker        */
1757*61046927SAndroid Build Coastguard Worker       deny_props &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
1758*61046927SAndroid Build Coastguard Worker       return wsi_select_memory_type(wsi, req_props, deny_props, type_bits);
1759*61046927SAndroid Build Coastguard Worker    }
1760*61046927SAndroid Build Coastguard Worker 
1761*61046927SAndroid Build Coastguard Worker    unreachable("No memory type found");
1762*61046927SAndroid Build Coastguard Worker }
1763*61046927SAndroid Build Coastguard Worker 
1764*61046927SAndroid Build Coastguard Worker uint32_t
wsi_select_device_memory_type(const struct wsi_device * wsi,uint32_t type_bits)1765*61046927SAndroid Build Coastguard Worker wsi_select_device_memory_type(const struct wsi_device *wsi,
1766*61046927SAndroid Build Coastguard Worker                               uint32_t type_bits)
1767*61046927SAndroid Build Coastguard Worker {
1768*61046927SAndroid Build Coastguard Worker    return wsi_select_memory_type(wsi, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
1769*61046927SAndroid Build Coastguard Worker                                  0 /* deny_props */, type_bits);
1770*61046927SAndroid Build Coastguard Worker }
1771*61046927SAndroid Build Coastguard Worker 
1772*61046927SAndroid Build Coastguard Worker static uint32_t
wsi_select_host_memory_type(const struct wsi_device * wsi,uint32_t type_bits)1773*61046927SAndroid Build Coastguard Worker wsi_select_host_memory_type(const struct wsi_device *wsi,
1774*61046927SAndroid Build Coastguard Worker                             uint32_t type_bits)
1775*61046927SAndroid Build Coastguard Worker {
1776*61046927SAndroid Build Coastguard Worker    return wsi_select_memory_type(wsi, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
1777*61046927SAndroid Build Coastguard Worker                                  0 /* deny_props */, type_bits);
1778*61046927SAndroid Build Coastguard Worker }
1779*61046927SAndroid Build Coastguard Worker 
1780*61046927SAndroid Build Coastguard Worker VkResult
wsi_create_buffer_blit_context(const struct wsi_swapchain * chain,const struct wsi_image_info * info,struct wsi_image * image,VkExternalMemoryHandleTypeFlags handle_types)1781*61046927SAndroid Build Coastguard Worker wsi_create_buffer_blit_context(const struct wsi_swapchain *chain,
1782*61046927SAndroid Build Coastguard Worker                                const struct wsi_image_info *info,
1783*61046927SAndroid Build Coastguard Worker                                struct wsi_image *image,
1784*61046927SAndroid Build Coastguard Worker                                VkExternalMemoryHandleTypeFlags handle_types)
1785*61046927SAndroid Build Coastguard Worker {
1786*61046927SAndroid Build Coastguard Worker    assert(chain->blit.type == WSI_SWAPCHAIN_BUFFER_BLIT);
1787*61046927SAndroid Build Coastguard Worker 
1788*61046927SAndroid Build Coastguard Worker    const struct wsi_device *wsi = chain->wsi;
1789*61046927SAndroid Build Coastguard Worker    VkResult result;
1790*61046927SAndroid Build Coastguard Worker 
1791*61046927SAndroid Build Coastguard Worker    const VkExternalMemoryBufferCreateInfo buffer_external_info = {
1792*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
1793*61046927SAndroid Build Coastguard Worker       .pNext = NULL,
1794*61046927SAndroid Build Coastguard Worker       .handleTypes = handle_types,
1795*61046927SAndroid Build Coastguard Worker    };
1796*61046927SAndroid Build Coastguard Worker    const VkBufferCreateInfo buffer_info = {
1797*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1798*61046927SAndroid Build Coastguard Worker       .pNext = &buffer_external_info,
1799*61046927SAndroid Build Coastguard Worker       .size = info->linear_size,
1800*61046927SAndroid Build Coastguard Worker       .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1801*61046927SAndroid Build Coastguard Worker       .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
1802*61046927SAndroid Build Coastguard Worker    };
1803*61046927SAndroid Build Coastguard Worker    result = wsi->CreateBuffer(chain->device, &buffer_info,
1804*61046927SAndroid Build Coastguard Worker                               &chain->alloc, &image->blit.buffer);
1805*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1806*61046927SAndroid Build Coastguard Worker       return result;
1807*61046927SAndroid Build Coastguard Worker 
1808*61046927SAndroid Build Coastguard Worker    VkMemoryRequirements reqs;
1809*61046927SAndroid Build Coastguard Worker    wsi->GetBufferMemoryRequirements(chain->device, image->blit.buffer, &reqs);
1810*61046927SAndroid Build Coastguard Worker    assert(reqs.size <= info->linear_size);
1811*61046927SAndroid Build Coastguard Worker 
1812*61046927SAndroid Build Coastguard Worker    struct wsi_memory_allocate_info memory_wsi_info = {
1813*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO_MESA,
1814*61046927SAndroid Build Coastguard Worker       .pNext = NULL,
1815*61046927SAndroid Build Coastguard Worker       .implicit_sync = info->image_type == WSI_IMAGE_TYPE_DRM &&
1816*61046927SAndroid Build Coastguard Worker                        !info->explicit_sync,
1817*61046927SAndroid Build Coastguard Worker    };
1818*61046927SAndroid Build Coastguard Worker    VkMemoryDedicatedAllocateInfo buf_mem_dedicated_info = {
1819*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
1820*61046927SAndroid Build Coastguard Worker       .pNext = &memory_wsi_info,
1821*61046927SAndroid Build Coastguard Worker       .image = VK_NULL_HANDLE,
1822*61046927SAndroid Build Coastguard Worker       .buffer = image->blit.buffer,
1823*61046927SAndroid Build Coastguard Worker    };
1824*61046927SAndroid Build Coastguard Worker    VkMemoryAllocateInfo buf_mem_info = {
1825*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1826*61046927SAndroid Build Coastguard Worker       .pNext = &buf_mem_dedicated_info,
1827*61046927SAndroid Build Coastguard Worker       .allocationSize = info->linear_size,
1828*61046927SAndroid Build Coastguard Worker       .memoryTypeIndex =
1829*61046927SAndroid Build Coastguard Worker          info->select_blit_dst_memory_type(wsi, reqs.memoryTypeBits),
1830*61046927SAndroid Build Coastguard Worker    };
1831*61046927SAndroid Build Coastguard Worker 
1832*61046927SAndroid Build Coastguard Worker    void *sw_host_ptr = NULL;
1833*61046927SAndroid Build Coastguard Worker    if (info->alloc_shm)
1834*61046927SAndroid Build Coastguard Worker       sw_host_ptr = info->alloc_shm(image, info->linear_size);
1835*61046927SAndroid Build Coastguard Worker 
1836*61046927SAndroid Build Coastguard Worker    VkExportMemoryAllocateInfo memory_export_info;
1837*61046927SAndroid Build Coastguard Worker    VkImportMemoryHostPointerInfoEXT host_ptr_info;
1838*61046927SAndroid Build Coastguard Worker    if (sw_host_ptr != NULL) {
1839*61046927SAndroid Build Coastguard Worker       host_ptr_info = (VkImportMemoryHostPointerInfoEXT) {
1840*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT,
1841*61046927SAndroid Build Coastguard Worker          .pHostPointer = sw_host_ptr,
1842*61046927SAndroid Build Coastguard Worker          .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT,
1843*61046927SAndroid Build Coastguard Worker       };
1844*61046927SAndroid Build Coastguard Worker       __vk_append_struct(&buf_mem_info, &host_ptr_info);
1845*61046927SAndroid Build Coastguard Worker    } else if (handle_types != 0) {
1846*61046927SAndroid Build Coastguard Worker       memory_export_info = (VkExportMemoryAllocateInfo) {
1847*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
1848*61046927SAndroid Build Coastguard Worker          .handleTypes = handle_types,
1849*61046927SAndroid Build Coastguard Worker       };
1850*61046927SAndroid Build Coastguard Worker       __vk_append_struct(&buf_mem_info, &memory_export_info);
1851*61046927SAndroid Build Coastguard Worker    }
1852*61046927SAndroid Build Coastguard Worker 
1853*61046927SAndroid Build Coastguard Worker    result = wsi->AllocateMemory(chain->device, &buf_mem_info,
1854*61046927SAndroid Build Coastguard Worker                                 &chain->alloc, &image->blit.memory);
1855*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1856*61046927SAndroid Build Coastguard Worker       return result;
1857*61046927SAndroid Build Coastguard Worker 
1858*61046927SAndroid Build Coastguard Worker    result = wsi->BindBufferMemory(chain->device, image->blit.buffer,
1859*61046927SAndroid Build Coastguard Worker                                   image->blit.memory, 0);
1860*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1861*61046927SAndroid Build Coastguard Worker       return result;
1862*61046927SAndroid Build Coastguard Worker 
1863*61046927SAndroid Build Coastguard Worker    wsi->GetImageMemoryRequirements(chain->device, image->image, &reqs);
1864*61046927SAndroid Build Coastguard Worker 
1865*61046927SAndroid Build Coastguard Worker    const VkMemoryDedicatedAllocateInfo memory_dedicated_info = {
1866*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
1867*61046927SAndroid Build Coastguard Worker       .pNext = NULL,
1868*61046927SAndroid Build Coastguard Worker       .image = image->image,
1869*61046927SAndroid Build Coastguard Worker       .buffer = VK_NULL_HANDLE,
1870*61046927SAndroid Build Coastguard Worker    };
1871*61046927SAndroid Build Coastguard Worker    const VkMemoryAllocateInfo memory_info = {
1872*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1873*61046927SAndroid Build Coastguard Worker       .pNext = &memory_dedicated_info,
1874*61046927SAndroid Build Coastguard Worker       .allocationSize = reqs.size,
1875*61046927SAndroid Build Coastguard Worker       .memoryTypeIndex =
1876*61046927SAndroid Build Coastguard Worker          info->select_image_memory_type(wsi, reqs.memoryTypeBits),
1877*61046927SAndroid Build Coastguard Worker    };
1878*61046927SAndroid Build Coastguard Worker 
1879*61046927SAndroid Build Coastguard Worker    result = wsi->AllocateMemory(chain->device, &memory_info,
1880*61046927SAndroid Build Coastguard Worker                                 &chain->alloc, &image->memory);
1881*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1882*61046927SAndroid Build Coastguard Worker       return result;
1883*61046927SAndroid Build Coastguard Worker 
1884*61046927SAndroid Build Coastguard Worker    image->num_planes = 1;
1885*61046927SAndroid Build Coastguard Worker    image->sizes[0] = info->linear_size;
1886*61046927SAndroid Build Coastguard Worker    image->row_pitches[0] = info->linear_stride;
1887*61046927SAndroid Build Coastguard Worker    image->offsets[0] = 0;
1888*61046927SAndroid Build Coastguard Worker 
1889*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1890*61046927SAndroid Build Coastguard Worker }
1891*61046927SAndroid Build Coastguard Worker 
1892*61046927SAndroid Build Coastguard Worker VkResult
wsi_finish_create_blit_context(const struct wsi_swapchain * chain,const struct wsi_image_info * info,struct wsi_image * image)1893*61046927SAndroid Build Coastguard Worker wsi_finish_create_blit_context(const struct wsi_swapchain *chain,
1894*61046927SAndroid Build Coastguard Worker                                const struct wsi_image_info *info,
1895*61046927SAndroid Build Coastguard Worker                                struct wsi_image *image)
1896*61046927SAndroid Build Coastguard Worker {
1897*61046927SAndroid Build Coastguard Worker    const struct wsi_device *wsi = chain->wsi;
1898*61046927SAndroid Build Coastguard Worker    VkResult result;
1899*61046927SAndroid Build Coastguard Worker 
1900*61046927SAndroid Build Coastguard Worker    int cmd_buffer_count =
1901*61046927SAndroid Build Coastguard Worker       chain->blit.queue != VK_NULL_HANDLE ? 1 : wsi->queue_family_count;
1902*61046927SAndroid Build Coastguard Worker    image->blit.cmd_buffers =
1903*61046927SAndroid Build Coastguard Worker       vk_zalloc(&chain->alloc,
1904*61046927SAndroid Build Coastguard Worker                 sizeof(VkCommandBuffer) * cmd_buffer_count, 8,
1905*61046927SAndroid Build Coastguard Worker                 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1906*61046927SAndroid Build Coastguard Worker    if (!image->blit.cmd_buffers)
1907*61046927SAndroid Build Coastguard Worker       return VK_ERROR_OUT_OF_HOST_MEMORY;
1908*61046927SAndroid Build Coastguard Worker 
1909*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < cmd_buffer_count; i++) {
1910*61046927SAndroid Build Coastguard Worker       if (!chain->cmd_pools[i])
1911*61046927SAndroid Build Coastguard Worker          continue;
1912*61046927SAndroid Build Coastguard Worker 
1913*61046927SAndroid Build Coastguard Worker       const VkCommandBufferAllocateInfo cmd_buffer_info = {
1914*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
1915*61046927SAndroid Build Coastguard Worker          .pNext = NULL,
1916*61046927SAndroid Build Coastguard Worker          .commandPool = chain->cmd_pools[i],
1917*61046927SAndroid Build Coastguard Worker          .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
1918*61046927SAndroid Build Coastguard Worker          .commandBufferCount = 1,
1919*61046927SAndroid Build Coastguard Worker       };
1920*61046927SAndroid Build Coastguard Worker       result = wsi->AllocateCommandBuffers(chain->device, &cmd_buffer_info,
1921*61046927SAndroid Build Coastguard Worker                                            &image->blit.cmd_buffers[i]);
1922*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
1923*61046927SAndroid Build Coastguard Worker          return result;
1924*61046927SAndroid Build Coastguard Worker 
1925*61046927SAndroid Build Coastguard Worker       const VkCommandBufferBeginInfo begin_info = {
1926*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1927*61046927SAndroid Build Coastguard Worker       };
1928*61046927SAndroid Build Coastguard Worker       wsi->BeginCommandBuffer(image->blit.cmd_buffers[i], &begin_info);
1929*61046927SAndroid Build Coastguard Worker 
1930*61046927SAndroid Build Coastguard Worker       VkImageMemoryBarrier img_mem_barriers[] = {
1931*61046927SAndroid Build Coastguard Worker          {
1932*61046927SAndroid Build Coastguard Worker             .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
1933*61046927SAndroid Build Coastguard Worker             .pNext = NULL,
1934*61046927SAndroid Build Coastguard Worker             .srcAccessMask = 0,
1935*61046927SAndroid Build Coastguard Worker             .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
1936*61046927SAndroid Build Coastguard Worker             .oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
1937*61046927SAndroid Build Coastguard Worker             .newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1938*61046927SAndroid Build Coastguard Worker             .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
1939*61046927SAndroid Build Coastguard Worker             .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
1940*61046927SAndroid Build Coastguard Worker             .image = image->image,
1941*61046927SAndroid Build Coastguard Worker             .subresourceRange = {
1942*61046927SAndroid Build Coastguard Worker                .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1943*61046927SAndroid Build Coastguard Worker                .baseMipLevel = 0,
1944*61046927SAndroid Build Coastguard Worker                .levelCount = 1,
1945*61046927SAndroid Build Coastguard Worker                .baseArrayLayer = 0,
1946*61046927SAndroid Build Coastguard Worker                .layerCount = 1,
1947*61046927SAndroid Build Coastguard Worker             },
1948*61046927SAndroid Build Coastguard Worker          },
1949*61046927SAndroid Build Coastguard Worker          {
1950*61046927SAndroid Build Coastguard Worker             .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
1951*61046927SAndroid Build Coastguard Worker             .pNext = NULL,
1952*61046927SAndroid Build Coastguard Worker             .srcAccessMask = 0,
1953*61046927SAndroid Build Coastguard Worker             .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
1954*61046927SAndroid Build Coastguard Worker             .oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
1955*61046927SAndroid Build Coastguard Worker             .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1956*61046927SAndroid Build Coastguard Worker             .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
1957*61046927SAndroid Build Coastguard Worker             .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
1958*61046927SAndroid Build Coastguard Worker             .image = image->blit.image,
1959*61046927SAndroid Build Coastguard Worker             .subresourceRange = {
1960*61046927SAndroid Build Coastguard Worker                .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1961*61046927SAndroid Build Coastguard Worker                .baseMipLevel = 0,
1962*61046927SAndroid Build Coastguard Worker                .levelCount = 1,
1963*61046927SAndroid Build Coastguard Worker                .baseArrayLayer = 0,
1964*61046927SAndroid Build Coastguard Worker                .layerCount = 1,
1965*61046927SAndroid Build Coastguard Worker             },
1966*61046927SAndroid Build Coastguard Worker          },
1967*61046927SAndroid Build Coastguard Worker       };
1968*61046927SAndroid Build Coastguard Worker       uint32_t img_mem_barrier_count =
1969*61046927SAndroid Build Coastguard Worker          chain->blit.type == WSI_SWAPCHAIN_BUFFER_BLIT ? 1 : 2;
1970*61046927SAndroid Build Coastguard Worker       wsi->CmdPipelineBarrier(image->blit.cmd_buffers[i],
1971*61046927SAndroid Build Coastguard Worker                               VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1972*61046927SAndroid Build Coastguard Worker                               VK_PIPELINE_STAGE_TRANSFER_BIT,
1973*61046927SAndroid Build Coastguard Worker                               0,
1974*61046927SAndroid Build Coastguard Worker                               0, NULL,
1975*61046927SAndroid Build Coastguard Worker                               0, NULL,
1976*61046927SAndroid Build Coastguard Worker                               1, img_mem_barriers);
1977*61046927SAndroid Build Coastguard Worker 
1978*61046927SAndroid Build Coastguard Worker       if (chain->blit.type == WSI_SWAPCHAIN_BUFFER_BLIT) {
1979*61046927SAndroid Build Coastguard Worker          struct VkBufferImageCopy buffer_image_copy = {
1980*61046927SAndroid Build Coastguard Worker             .bufferOffset = 0,
1981*61046927SAndroid Build Coastguard Worker             .bufferRowLength = info->linear_stride /
1982*61046927SAndroid Build Coastguard Worker                                vk_format_get_blocksize(info->create.format),
1983*61046927SAndroid Build Coastguard Worker             .bufferImageHeight = 0,
1984*61046927SAndroid Build Coastguard Worker             .imageSubresource = {
1985*61046927SAndroid Build Coastguard Worker                .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1986*61046927SAndroid Build Coastguard Worker                .mipLevel = 0,
1987*61046927SAndroid Build Coastguard Worker                .baseArrayLayer = 0,
1988*61046927SAndroid Build Coastguard Worker                .layerCount = 1,
1989*61046927SAndroid Build Coastguard Worker             },
1990*61046927SAndroid Build Coastguard Worker             .imageOffset = { .x = 0, .y = 0, .z = 0 },
1991*61046927SAndroid Build Coastguard Worker             .imageExtent = info->create.extent,
1992*61046927SAndroid Build Coastguard Worker          };
1993*61046927SAndroid Build Coastguard Worker          wsi->CmdCopyImageToBuffer(image->blit.cmd_buffers[i],
1994*61046927SAndroid Build Coastguard Worker                                    image->image,
1995*61046927SAndroid Build Coastguard Worker                                    VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1996*61046927SAndroid Build Coastguard Worker                                    image->blit.buffer,
1997*61046927SAndroid Build Coastguard Worker                                    1, &buffer_image_copy);
1998*61046927SAndroid Build Coastguard Worker       } else {
1999*61046927SAndroid Build Coastguard Worker          struct VkImageCopy image_copy = {
2000*61046927SAndroid Build Coastguard Worker             .srcSubresource = {
2001*61046927SAndroid Build Coastguard Worker                .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
2002*61046927SAndroid Build Coastguard Worker                .mipLevel = 0,
2003*61046927SAndroid Build Coastguard Worker                .baseArrayLayer = 0,
2004*61046927SAndroid Build Coastguard Worker                .layerCount = 1,
2005*61046927SAndroid Build Coastguard Worker             },
2006*61046927SAndroid Build Coastguard Worker             .srcOffset = { .x = 0, .y = 0, .z = 0 },
2007*61046927SAndroid Build Coastguard Worker             .dstSubresource = {
2008*61046927SAndroid Build Coastguard Worker                .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
2009*61046927SAndroid Build Coastguard Worker                .mipLevel = 0,
2010*61046927SAndroid Build Coastguard Worker                .baseArrayLayer = 0,
2011*61046927SAndroid Build Coastguard Worker                .layerCount = 1,
2012*61046927SAndroid Build Coastguard Worker             },
2013*61046927SAndroid Build Coastguard Worker             .dstOffset = { .x = 0, .y = 0, .z = 0 },
2014*61046927SAndroid Build Coastguard Worker             .extent = info->create.extent,
2015*61046927SAndroid Build Coastguard Worker          };
2016*61046927SAndroid Build Coastguard Worker 
2017*61046927SAndroid Build Coastguard Worker          wsi->CmdCopyImage(image->blit.cmd_buffers[i],
2018*61046927SAndroid Build Coastguard Worker                            image->image,
2019*61046927SAndroid Build Coastguard Worker                            VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2020*61046927SAndroid Build Coastguard Worker                            image->blit.image,
2021*61046927SAndroid Build Coastguard Worker                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2022*61046927SAndroid Build Coastguard Worker                            1, &image_copy);
2023*61046927SAndroid Build Coastguard Worker       }
2024*61046927SAndroid Build Coastguard Worker 
2025*61046927SAndroid Build Coastguard Worker       img_mem_barriers[0].srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
2026*61046927SAndroid Build Coastguard Worker       img_mem_barriers[0].dstAccessMask = 0;
2027*61046927SAndroid Build Coastguard Worker       img_mem_barriers[0].oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
2028*61046927SAndroid Build Coastguard Worker       img_mem_barriers[0].newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
2029*61046927SAndroid Build Coastguard Worker       img_mem_barriers[1].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
2030*61046927SAndroid Build Coastguard Worker       img_mem_barriers[1].dstAccessMask = 0;
2031*61046927SAndroid Build Coastguard Worker       img_mem_barriers[1].oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
2032*61046927SAndroid Build Coastguard Worker       img_mem_barriers[1].newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
2033*61046927SAndroid Build Coastguard Worker       wsi->CmdPipelineBarrier(image->blit.cmd_buffers[i],
2034*61046927SAndroid Build Coastguard Worker                               VK_PIPELINE_STAGE_TRANSFER_BIT,
2035*61046927SAndroid Build Coastguard Worker                               VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
2036*61046927SAndroid Build Coastguard Worker                               0,
2037*61046927SAndroid Build Coastguard Worker                               0, NULL,
2038*61046927SAndroid Build Coastguard Worker                               0, NULL,
2039*61046927SAndroid Build Coastguard Worker                               img_mem_barrier_count, img_mem_barriers);
2040*61046927SAndroid Build Coastguard Worker 
2041*61046927SAndroid Build Coastguard Worker       result = wsi->EndCommandBuffer(image->blit.cmd_buffers[i]);
2042*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
2043*61046927SAndroid Build Coastguard Worker          return result;
2044*61046927SAndroid Build Coastguard Worker    }
2045*61046927SAndroid Build Coastguard Worker 
2046*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2047*61046927SAndroid Build Coastguard Worker }
2048*61046927SAndroid Build Coastguard Worker 
2049*61046927SAndroid Build Coastguard Worker void
wsi_configure_buffer_image(UNUSED const struct wsi_swapchain * chain,const VkSwapchainCreateInfoKHR * pCreateInfo,uint32_t stride_align,uint32_t size_align,struct wsi_image_info * info)2050*61046927SAndroid Build Coastguard Worker wsi_configure_buffer_image(UNUSED const struct wsi_swapchain *chain,
2051*61046927SAndroid Build Coastguard Worker                            const VkSwapchainCreateInfoKHR *pCreateInfo,
2052*61046927SAndroid Build Coastguard Worker                            uint32_t stride_align, uint32_t size_align,
2053*61046927SAndroid Build Coastguard Worker                            struct wsi_image_info *info)
2054*61046927SAndroid Build Coastguard Worker {
2055*61046927SAndroid Build Coastguard Worker    const struct wsi_device *wsi = chain->wsi;
2056*61046927SAndroid Build Coastguard Worker 
2057*61046927SAndroid Build Coastguard Worker    assert(util_is_power_of_two_nonzero(stride_align));
2058*61046927SAndroid Build Coastguard Worker    assert(util_is_power_of_two_nonzero(size_align));
2059*61046927SAndroid Build Coastguard Worker 
2060*61046927SAndroid Build Coastguard Worker    info->create.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2061*61046927SAndroid Build Coastguard Worker    info->wsi.blit_src = true;
2062*61046927SAndroid Build Coastguard Worker 
2063*61046927SAndroid Build Coastguard Worker    const uint32_t cpp = vk_format_get_blocksize(pCreateInfo->imageFormat);
2064*61046927SAndroid Build Coastguard Worker    info->linear_stride = pCreateInfo->imageExtent.width * cpp;
2065*61046927SAndroid Build Coastguard Worker    info->linear_stride = align(info->linear_stride, stride_align);
2066*61046927SAndroid Build Coastguard Worker 
2067*61046927SAndroid Build Coastguard Worker    /* Since we can pick the stride to be whatever we want, also align to the
2068*61046927SAndroid Build Coastguard Worker     * device's optimalBufferCopyRowPitchAlignment so we get efficient copies.
2069*61046927SAndroid Build Coastguard Worker     */
2070*61046927SAndroid Build Coastguard Worker    assert(wsi->optimalBufferCopyRowPitchAlignment > 0);
2071*61046927SAndroid Build Coastguard Worker    info->linear_stride = align(info->linear_stride,
2072*61046927SAndroid Build Coastguard Worker                                wsi->optimalBufferCopyRowPitchAlignment);
2073*61046927SAndroid Build Coastguard Worker 
2074*61046927SAndroid Build Coastguard Worker    info->linear_size = (uint64_t)info->linear_stride *
2075*61046927SAndroid Build Coastguard Worker                        pCreateInfo->imageExtent.height;
2076*61046927SAndroid Build Coastguard Worker    info->linear_size = align64(info->linear_size, size_align);
2077*61046927SAndroid Build Coastguard Worker 
2078*61046927SAndroid Build Coastguard Worker    info->finish_create = wsi_finish_create_blit_context;
2079*61046927SAndroid Build Coastguard Worker }
2080*61046927SAndroid Build Coastguard Worker 
2081*61046927SAndroid Build Coastguard Worker void
wsi_configure_image_blit_image(UNUSED const struct wsi_swapchain * chain,struct wsi_image_info * info)2082*61046927SAndroid Build Coastguard Worker wsi_configure_image_blit_image(UNUSED const struct wsi_swapchain *chain,
2083*61046927SAndroid Build Coastguard Worker                                struct wsi_image_info *info)
2084*61046927SAndroid Build Coastguard Worker {
2085*61046927SAndroid Build Coastguard Worker    info->create.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2086*61046927SAndroid Build Coastguard Worker    info->wsi.blit_src = true;
2087*61046927SAndroid Build Coastguard Worker    info->finish_create = wsi_finish_create_blit_context;
2088*61046927SAndroid Build Coastguard Worker }
2089*61046927SAndroid Build Coastguard Worker 
2090*61046927SAndroid Build Coastguard Worker static VkResult
wsi_create_cpu_linear_image_mem(const struct wsi_swapchain * chain,const struct wsi_image_info * info,struct wsi_image * image)2091*61046927SAndroid Build Coastguard Worker wsi_create_cpu_linear_image_mem(const struct wsi_swapchain *chain,
2092*61046927SAndroid Build Coastguard Worker                                 const struct wsi_image_info *info,
2093*61046927SAndroid Build Coastguard Worker                                 struct wsi_image *image)
2094*61046927SAndroid Build Coastguard Worker {
2095*61046927SAndroid Build Coastguard Worker    const struct wsi_device *wsi = chain->wsi;
2096*61046927SAndroid Build Coastguard Worker    VkResult result;
2097*61046927SAndroid Build Coastguard Worker 
2098*61046927SAndroid Build Coastguard Worker    VkMemoryRequirements reqs;
2099*61046927SAndroid Build Coastguard Worker    wsi->GetImageMemoryRequirements(chain->device, image->image, &reqs);
2100*61046927SAndroid Build Coastguard Worker 
2101*61046927SAndroid Build Coastguard Worker    VkSubresourceLayout layout;
2102*61046927SAndroid Build Coastguard Worker    wsi->GetImageSubresourceLayout(chain->device, image->image,
2103*61046927SAndroid Build Coastguard Worker                                   &(VkImageSubresource) {
2104*61046927SAndroid Build Coastguard Worker                                      .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
2105*61046927SAndroid Build Coastguard Worker                                      .mipLevel = 0,
2106*61046927SAndroid Build Coastguard Worker                                      .arrayLayer = 0,
2107*61046927SAndroid Build Coastguard Worker                                   }, &layout);
2108*61046927SAndroid Build Coastguard Worker    assert(layout.offset == 0);
2109*61046927SAndroid Build Coastguard Worker 
2110*61046927SAndroid Build Coastguard Worker    const VkMemoryDedicatedAllocateInfo memory_dedicated_info = {
2111*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
2112*61046927SAndroid Build Coastguard Worker       .image = image->image,
2113*61046927SAndroid Build Coastguard Worker       .buffer = VK_NULL_HANDLE,
2114*61046927SAndroid Build Coastguard Worker    };
2115*61046927SAndroid Build Coastguard Worker    VkMemoryAllocateInfo memory_info = {
2116*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
2117*61046927SAndroid Build Coastguard Worker       .pNext = &memory_dedicated_info,
2118*61046927SAndroid Build Coastguard Worker       .allocationSize = reqs.size,
2119*61046927SAndroid Build Coastguard Worker       .memoryTypeIndex =
2120*61046927SAndroid Build Coastguard Worker          wsi_select_host_memory_type(wsi, reqs.memoryTypeBits),
2121*61046927SAndroid Build Coastguard Worker    };
2122*61046927SAndroid Build Coastguard Worker 
2123*61046927SAndroid Build Coastguard Worker    void *sw_host_ptr = NULL;
2124*61046927SAndroid Build Coastguard Worker    if (info->alloc_shm)
2125*61046927SAndroid Build Coastguard Worker       sw_host_ptr = info->alloc_shm(image, layout.size);
2126*61046927SAndroid Build Coastguard Worker 
2127*61046927SAndroid Build Coastguard Worker    VkImportMemoryHostPointerInfoEXT host_ptr_info;
2128*61046927SAndroid Build Coastguard Worker    if (sw_host_ptr != NULL) {
2129*61046927SAndroid Build Coastguard Worker       host_ptr_info = (VkImportMemoryHostPointerInfoEXT) {
2130*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT,
2131*61046927SAndroid Build Coastguard Worker          .pHostPointer = sw_host_ptr,
2132*61046927SAndroid Build Coastguard Worker          .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT,
2133*61046927SAndroid Build Coastguard Worker       };
2134*61046927SAndroid Build Coastguard Worker       __vk_append_struct(&memory_info, &host_ptr_info);
2135*61046927SAndroid Build Coastguard Worker    }
2136*61046927SAndroid Build Coastguard Worker 
2137*61046927SAndroid Build Coastguard Worker    result = wsi->AllocateMemory(chain->device, &memory_info,
2138*61046927SAndroid Build Coastguard Worker                                 &chain->alloc, &image->memory);
2139*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
2140*61046927SAndroid Build Coastguard Worker       return result;
2141*61046927SAndroid Build Coastguard Worker 
2142*61046927SAndroid Build Coastguard Worker    result = wsi->MapMemory(chain->device, image->memory,
2143*61046927SAndroid Build Coastguard Worker                            0, VK_WHOLE_SIZE, 0, &image->cpu_map);
2144*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
2145*61046927SAndroid Build Coastguard Worker       return result;
2146*61046927SAndroid Build Coastguard Worker 
2147*61046927SAndroid Build Coastguard Worker    image->num_planes = 1;
2148*61046927SAndroid Build Coastguard Worker    image->sizes[0] = reqs.size;
2149*61046927SAndroid Build Coastguard Worker    image->row_pitches[0] = layout.rowPitch;
2150*61046927SAndroid Build Coastguard Worker    image->offsets[0] = 0;
2151*61046927SAndroid Build Coastguard Worker 
2152*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2153*61046927SAndroid Build Coastguard Worker }
2154*61046927SAndroid Build Coastguard Worker 
2155*61046927SAndroid Build Coastguard Worker static VkResult
wsi_create_cpu_buffer_image_mem(const struct wsi_swapchain * chain,const struct wsi_image_info * info,struct wsi_image * image)2156*61046927SAndroid Build Coastguard Worker wsi_create_cpu_buffer_image_mem(const struct wsi_swapchain *chain,
2157*61046927SAndroid Build Coastguard Worker                                 const struct wsi_image_info *info,
2158*61046927SAndroid Build Coastguard Worker                                 struct wsi_image *image)
2159*61046927SAndroid Build Coastguard Worker {
2160*61046927SAndroid Build Coastguard Worker    VkResult result;
2161*61046927SAndroid Build Coastguard Worker 
2162*61046927SAndroid Build Coastguard Worker    result = wsi_create_buffer_blit_context(chain, info, image, 0);
2163*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
2164*61046927SAndroid Build Coastguard Worker       return result;
2165*61046927SAndroid Build Coastguard Worker 
2166*61046927SAndroid Build Coastguard Worker    result = chain->wsi->MapMemory(chain->device, image->blit.memory,
2167*61046927SAndroid Build Coastguard Worker                                   0, VK_WHOLE_SIZE, 0, &image->cpu_map);
2168*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
2169*61046927SAndroid Build Coastguard Worker       return result;
2170*61046927SAndroid Build Coastguard Worker 
2171*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2172*61046927SAndroid Build Coastguard Worker }
2173*61046927SAndroid Build Coastguard Worker 
2174*61046927SAndroid Build Coastguard Worker bool
wsi_cpu_image_needs_buffer_blit(const struct wsi_device * wsi,const struct wsi_cpu_image_params * params)2175*61046927SAndroid Build Coastguard Worker wsi_cpu_image_needs_buffer_blit(const struct wsi_device *wsi,
2176*61046927SAndroid Build Coastguard Worker                                 const struct wsi_cpu_image_params *params)
2177*61046927SAndroid Build Coastguard Worker {
2178*61046927SAndroid Build Coastguard Worker    if (WSI_DEBUG & WSI_DEBUG_BUFFER)
2179*61046927SAndroid Build Coastguard Worker       return true;
2180*61046927SAndroid Build Coastguard Worker 
2181*61046927SAndroid Build Coastguard Worker    if (wsi->wants_linear)
2182*61046927SAndroid Build Coastguard Worker       return false;
2183*61046927SAndroid Build Coastguard Worker 
2184*61046927SAndroid Build Coastguard Worker    return true;
2185*61046927SAndroid Build Coastguard Worker }
2186*61046927SAndroid Build Coastguard Worker 
2187*61046927SAndroid Build Coastguard Worker VkResult
wsi_configure_cpu_image(const struct wsi_swapchain * chain,const VkSwapchainCreateInfoKHR * pCreateInfo,const struct wsi_cpu_image_params * params,struct wsi_image_info * info)2188*61046927SAndroid Build Coastguard Worker wsi_configure_cpu_image(const struct wsi_swapchain *chain,
2189*61046927SAndroid Build Coastguard Worker                         const VkSwapchainCreateInfoKHR *pCreateInfo,
2190*61046927SAndroid Build Coastguard Worker                         const struct wsi_cpu_image_params *params,
2191*61046927SAndroid Build Coastguard Worker                         struct wsi_image_info *info)
2192*61046927SAndroid Build Coastguard Worker {
2193*61046927SAndroid Build Coastguard Worker    assert(params->base.image_type == WSI_IMAGE_TYPE_CPU);
2194*61046927SAndroid Build Coastguard Worker    assert(chain->blit.type == WSI_SWAPCHAIN_NO_BLIT ||
2195*61046927SAndroid Build Coastguard Worker           chain->blit.type == WSI_SWAPCHAIN_BUFFER_BLIT);
2196*61046927SAndroid Build Coastguard Worker 
2197*61046927SAndroid Build Coastguard Worker    VkExternalMemoryHandleTypeFlags handle_types = 0;
2198*61046927SAndroid Build Coastguard Worker    if (params->alloc_shm && chain->blit.type != WSI_SWAPCHAIN_NO_BLIT)
2199*61046927SAndroid Build Coastguard Worker       handle_types = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
2200*61046927SAndroid Build Coastguard Worker 
2201*61046927SAndroid Build Coastguard Worker    VkResult result = wsi_configure_image(chain, pCreateInfo,
2202*61046927SAndroid Build Coastguard Worker                                          handle_types, info);
2203*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
2204*61046927SAndroid Build Coastguard Worker       return result;
2205*61046927SAndroid Build Coastguard Worker 
2206*61046927SAndroid Build Coastguard Worker    if (chain->blit.type != WSI_SWAPCHAIN_NO_BLIT) {
2207*61046927SAndroid Build Coastguard Worker       wsi_configure_buffer_image(chain, pCreateInfo,
2208*61046927SAndroid Build Coastguard Worker                                  1 /* stride_align */,
2209*61046927SAndroid Build Coastguard Worker                                  1 /* size_align */,
2210*61046927SAndroid Build Coastguard Worker                                  info);
2211*61046927SAndroid Build Coastguard Worker 
2212*61046927SAndroid Build Coastguard Worker       info->select_blit_dst_memory_type = wsi_select_host_memory_type;
2213*61046927SAndroid Build Coastguard Worker       info->select_image_memory_type = wsi_select_device_memory_type;
2214*61046927SAndroid Build Coastguard Worker       info->create_mem = wsi_create_cpu_buffer_image_mem;
2215*61046927SAndroid Build Coastguard Worker    } else {
2216*61046927SAndroid Build Coastguard Worker       /* Force the image to be linear */
2217*61046927SAndroid Build Coastguard Worker       info->create.tiling = VK_IMAGE_TILING_LINEAR;
2218*61046927SAndroid Build Coastguard Worker 
2219*61046927SAndroid Build Coastguard Worker       info->create_mem = wsi_create_cpu_linear_image_mem;
2220*61046927SAndroid Build Coastguard Worker    }
2221*61046927SAndroid Build Coastguard Worker 
2222*61046927SAndroid Build Coastguard Worker    info->alloc_shm = params->alloc_shm;
2223*61046927SAndroid Build Coastguard Worker 
2224*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2225*61046927SAndroid Build Coastguard Worker }
2226*61046927SAndroid Build Coastguard Worker 
2227*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
wsi_WaitForPresentKHR(VkDevice device,VkSwapchainKHR _swapchain,uint64_t presentId,uint64_t timeout)2228*61046927SAndroid Build Coastguard Worker wsi_WaitForPresentKHR(VkDevice device, VkSwapchainKHR _swapchain,
2229*61046927SAndroid Build Coastguard Worker                       uint64_t presentId, uint64_t timeout)
2230*61046927SAndroid Build Coastguard Worker {
2231*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain);
2232*61046927SAndroid Build Coastguard Worker    assert(swapchain->wait_for_present);
2233*61046927SAndroid Build Coastguard Worker    return swapchain->wait_for_present(swapchain, presentId, timeout);
2234*61046927SAndroid Build Coastguard Worker }
2235*61046927SAndroid Build Coastguard Worker 
2236*61046927SAndroid Build Coastguard Worker VkImageUsageFlags
wsi_caps_get_image_usage(void)2237*61046927SAndroid Build Coastguard Worker wsi_caps_get_image_usage(void)
2238*61046927SAndroid Build Coastguard Worker {
2239*61046927SAndroid Build Coastguard Worker    return VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2240*61046927SAndroid Build Coastguard Worker           VK_IMAGE_USAGE_SAMPLED_BIT |
2241*61046927SAndroid Build Coastguard Worker           VK_IMAGE_USAGE_TRANSFER_DST_BIT |
2242*61046927SAndroid Build Coastguard Worker           VK_IMAGE_USAGE_STORAGE_BIT |
2243*61046927SAndroid Build Coastguard Worker           VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
2244*61046927SAndroid Build Coastguard Worker           VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2245*61046927SAndroid Build Coastguard Worker }
2246*61046927SAndroid Build Coastguard Worker 
2247*61046927SAndroid Build Coastguard Worker bool
wsi_device_supports_explicit_sync(struct wsi_device * device)2248*61046927SAndroid Build Coastguard Worker wsi_device_supports_explicit_sync(struct wsi_device *device)
2249*61046927SAndroid Build Coastguard Worker {
2250*61046927SAndroid Build Coastguard Worker    return !device->sw && device->has_timeline_semaphore &&
2251*61046927SAndroid Build Coastguard Worker       (device->timeline_semaphore_export_handle_types &
2252*61046927SAndroid Build Coastguard Worker        VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT);
2253*61046927SAndroid Build Coastguard Worker }
2254