2017-11-16 02:50:44 +00:00
|
|
|
/*
|
|
|
|
* Copyright © 2017 Intel Corporation
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice (including the next
|
|
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
|
|
* Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
|
|
* IN THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
2017-11-16 04:08:53 +00:00
|
|
|
#include "wsi_common_private.h"
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
#include "wsi_common_entrypoints.h"
|
2017-11-16 03:04:10 +00:00
|
|
|
#include "util/macros.h"
|
2020-06-05 09:55:22 +01:00
|
|
|
#include "util/os_file.h"
|
2019-04-17 00:30:49 +01:00
|
|
|
#include "util/xmlconfig.h"
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
#include "vk_device.h"
|
2021-12-15 09:52:44 +00:00
|
|
|
#include "vk_fence.h"
|
2022-02-03 09:57:16 +00:00
|
|
|
#include "vk_format.h"
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
#include "vk_instance.h"
|
|
|
|
#include "vk_physical_device.h"
|
|
|
|
#include "vk_queue.h"
|
2021-12-15 09:52:44 +00:00
|
|
|
#include "vk_semaphore.h"
|
2017-11-16 01:52:39 +00:00
|
|
|
#include "vk_util.h"
|
2017-11-16 02:50:44 +00:00
|
|
|
|
2018-10-28 13:37:26 +00:00
|
|
|
#include <time.h>
|
2019-04-09 14:30:05 +01:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
2018-02-09 23:43:27 +00:00
|
|
|
|
2017-11-16 20:49:27 +00:00
|
|
|
VkResult
|
2017-11-16 02:50:44 +00:00
|
|
|
wsi_device_init(struct wsi_device *wsi,
|
|
|
|
VkPhysicalDevice pdevice,
|
2017-11-16 20:49:27 +00:00
|
|
|
WSI_FN_GetPhysicalDeviceProcAddr proc_addr,
|
vulkan: Add KHR_display extension using DRM [v10]
This adds support for the KHR_display extension support to the vulkan
WSI layer. Driver support will be added separately.
v2:
* fix double ;; in wsi_common_display.c
* Move mode list from wsi_display to wsi_display_connector
* Fix scope for wsi_display_mode andwsi_display_connector
allocs
* Switch all allocations to vk_zalloc instead of vk_alloc.
* Fix DRM failure in
wsi_display_get_physical_device_display_properties
When DRM fails, or when we don't have a master fd
(presumably due to application errors), just return 0
properties from this function, which is at least a valid
response.
* Use vk_outarray for all property queries
This is a bit less error-prone than open-coding the same
stuff.
* Remove VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR from surface caps
Until we have multi-plane support, we shouldn't pretend to
have any multi-plane semantics, even if undefined.
Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
* Simplify addition of VK_USE_PLATFORM_DISPLAY_KHR to
vulkan_wsi_args
Suggested-by: Eric Engestrom <eric.engestrom@imgtec.com>
v3:
Add separate 'display_fd' and 'render_fd' arguments to
wsi_device_init API. This allows drivers to use different FDs
for the different aspects of the device.
Use largest mode as display size when no preferred mode.
If the display doesn't provide a preferred mode, we'll assume
that the largest supported mode is the "physical size" of the
device and report that.
v4:
Make wsi_image_state enumeration values uppercase.
Follow more common mesa conventions.
Remove 'render_fd' from wsi_device_init API. The
wsi_common_display code doesn't use this fd at all, so stop
passing it in. This avoids any potential confusion over which
fd to use when creating display-relative object handles.
Remove call to wsi_create_prime_image which would never have
been reached as the necessary condition (use_prime_blit) is
never set.
whitespace cleanups in wsi_common_display.c
Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
Add depth/bpp info to available surface formats. Instead of
hard-coding depth 24 bpp 32 in the drmModeAddFB call, use the
requested format to find suitable values.
Destroy kernel buffers and FBs when swapchain is destroyed. We
were leaking both of these kernel objects across swapchain
destruction.
Note that wsi_display_wait_for_event waits for anything to
happen. wsi_display_wait_for_event is simply a yield so that
the caller can then check to see if the desired state change
has occurred.
Record swapchain failures in chain for later return. If some
asynchronous swapchain activity fails, we need to tell the
application eventually. Record the failure in the swapchain
and report it at the next acquire_next_image or queue_present
call.
Fix error returns from wsi_display_setup_connector. If a
malloc failed, then the result should be
VK_ERROR_OUT_OF_HOST_MEMORY. Otherwise, the associated ioctl
failed and we're either VT switched away, or our lease has
been revoked, in which case we should return
VK_ERROR_OUT_OF_DATE_KHR.
Make sure both sides of if/else brace use matches
Note that we assume drmModeSetCrtc is synchronous. Add a
comment explaining why we can idle any previous displayed
image as soon as the mode set returns.
Note that EACCES from drmModePageFlip means VT inactive. When
vt switched away drmModePageFlip returns EACCES. Poll once a
second waiting until we get some other return value back.
Clean up after alloc failure in
wsi_display_surface_create_swapchain. Destroy any created
images, free the swapchain.
Remove physical_device from wsi_display_init_wsi. We never
need this value, so remove it from the API and from the
internal wsi_display structure.
Use drmModeAddFB2 in wsi_display_image_init. This takes a drm
format instead of depth/bpp, which provides more control over
the format of the data.
v5:
Set the 'currentStackIndex' member of the
VkDisplayPlanePropertiesKHR record to zero, instead of
indexing across all displays. This value is the stack depth of
the plane within an individual display, and as the current
code supports only a single plane per display, should be set
to zero for all elements
Discovered-by: David Mao <David.Mao@amd.com>
v6:
Remove 'platform_display' bits from the build and use the
existing 'platform_drm' instead.
v7:
Ensure VK_ICD_WSI_PLATFORM_MAX is large enough by
setting to VK_ICD_WSI_PLATFORM_DISPLAY + 1
v8:
Simplify wsi_device_init failure from wsi_display_init_wsi
by using the same pattern as the other wsi layers.
Adopt Jason Ekstrand's white space and variable declaration
suggestions. Declare variables at first use, eliminate extra
whitespace between types and names, add list iterator helpers,
switch to lower-case list_ macros.
Respond to Jason's April 8 review:
* Create a function to convert relative to absolute timeouts
to catch overflow issues in one place
* use VK_NULL_HANDLE to clear prop->currentDisplay
* Get rid of available_present_modes array.
* return OUT_OF_DATE_KHR when display_queue_next called after
display has been released.
* Make errors from mode setting fatal in display_queue_next
* Remove duplicate pthread_mutex_init call
* Add wsi_init_pthread_cond_monotonic helper function to
isolate pthread error handling from wsi_display_init_wsi
Suggested-by: Jason Ekstrand <jason.ekstrand@intel.com>
v9:
Fix vscan handling by using MAX2(vscan, 1) everywhere. Vscan
can be zero anywhere, which is treated the same as 1.
Suggested-by: Jason Ekstrand <jason.ekstrand@intel.com>
v10:
Respond to Vulkan CTS failures.
1. Initialize planeReorderPossible in display_properties code
2. Only report connected displays in
get_display_plane_supported_displays
3. Return VK_ERROR_OUT_OF_HOST_MEMORY when pthread cond
initialization fails.
Signed-off-by: Jason Ekstrand <jason.ekstrand@intel.com>
4. Add vkCreateDisplayModeKHR. This doesn't actually create
new modes, it only looks to see if the requested parameters
matches an existing mode and returns that.
Suggested-by: Jason Ekstrand <jason.ekstrand@intel.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Signed-off-by: Keith Packard <keithp@keithp.com>
2018-02-07 18:31:44 +00:00
|
|
|
const VkAllocationCallbacks *alloc,
|
2019-04-17 00:30:49 +01:00
|
|
|
int display_fd,
|
2020-06-19 07:37:51 +01:00
|
|
|
const struct driOptionCache *dri_options,
|
|
|
|
bool sw_device)
|
2017-11-16 02:50:44 +00:00
|
|
|
{
|
2019-04-09 14:30:05 +01:00
|
|
|
const char *present_mode;
|
2019-12-17 03:58:39 +00:00
|
|
|
UNUSED VkResult result;
|
2017-11-16 20:49:27 +00:00
|
|
|
|
2017-11-16 02:50:44 +00:00
|
|
|
memset(wsi, 0, sizeof(*wsi));
|
2017-11-16 03:04:10 +00:00
|
|
|
|
2018-10-17 20:35:16 +01:00
|
|
|
wsi->instance_alloc = *alloc;
|
2018-02-09 23:43:27 +00:00
|
|
|
wsi->pdevice = pdevice;
|
2020-06-19 07:37:51 +01:00
|
|
|
wsi->sw = sw_device;
|
2017-11-16 03:04:10 +00:00
|
|
|
#define WSI_GET_CB(func) \
|
|
|
|
PFN_vk##func func = (PFN_vk##func)proc_addr(pdevice, "vk" #func)
|
2018-10-18 16:08:32 +01:00
|
|
|
WSI_GET_CB(GetPhysicalDeviceProperties2);
|
2017-11-16 03:04:10 +00:00
|
|
|
WSI_GET_CB(GetPhysicalDeviceMemoryProperties);
|
|
|
|
WSI_GET_CB(GetPhysicalDeviceQueueFamilyProperties);
|
|
|
|
#undef WSI_GET_CB
|
|
|
|
|
2018-10-18 16:08:32 +01:00
|
|
|
wsi->pci_bus_info.sType =
|
|
|
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT;
|
|
|
|
VkPhysicalDeviceProperties2 pdp2 = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
|
|
|
|
.pNext = &wsi->pci_bus_info,
|
|
|
|
};
|
|
|
|
GetPhysicalDeviceProperties2(pdevice, &pdp2);
|
|
|
|
|
2018-11-25 11:23:26 +00:00
|
|
|
wsi->maxImageDimension2D = pdp2.properties.limits.maxImageDimension2D;
|
2019-04-09 14:30:05 +01:00
|
|
|
wsi->override_present_mode = VK_PRESENT_MODE_MAX_ENUM_KHR;
|
2018-11-25 11:23:26 +00:00
|
|
|
|
2017-11-16 03:04:10 +00:00
|
|
|
GetPhysicalDeviceMemoryProperties(pdevice, &wsi->memory_props);
|
|
|
|
GetPhysicalDeviceQueueFamilyProperties(pdevice, &wsi->queue_family_count, NULL);
|
|
|
|
|
2021-11-01 05:31:19 +00:00
|
|
|
list_inithead(&wsi->hotplug_fences);
|
|
|
|
|
2017-11-16 03:04:10 +00:00
|
|
|
#define WSI_GET_CB(func) \
|
|
|
|
wsi->func = (PFN_vk##func)proc_addr(pdevice, "vk" #func)
|
|
|
|
WSI_GET_CB(AllocateMemory);
|
|
|
|
WSI_GET_CB(AllocateCommandBuffers);
|
|
|
|
WSI_GET_CB(BindBufferMemory);
|
|
|
|
WSI_GET_CB(BindImageMemory);
|
|
|
|
WSI_GET_CB(BeginCommandBuffer);
|
2021-07-19 14:32:19 +01:00
|
|
|
WSI_GET_CB(CmdPipelineBarrier);
|
2017-11-16 03:04:10 +00:00
|
|
|
WSI_GET_CB(CmdCopyImageToBuffer);
|
|
|
|
WSI_GET_CB(CreateBuffer);
|
|
|
|
WSI_GET_CB(CreateCommandPool);
|
2017-11-16 01:52:39 +00:00
|
|
|
WSI_GET_CB(CreateFence);
|
2017-11-16 03:04:10 +00:00
|
|
|
WSI_GET_CB(CreateImage);
|
2021-12-08 13:05:15 +00:00
|
|
|
WSI_GET_CB(CreateSemaphore);
|
2017-11-16 03:04:10 +00:00
|
|
|
WSI_GET_CB(DestroyBuffer);
|
|
|
|
WSI_GET_CB(DestroyCommandPool);
|
2017-11-16 01:52:39 +00:00
|
|
|
WSI_GET_CB(DestroyFence);
|
2017-11-16 03:04:10 +00:00
|
|
|
WSI_GET_CB(DestroyImage);
|
2021-12-08 13:05:15 +00:00
|
|
|
WSI_GET_CB(DestroySemaphore);
|
2017-11-16 03:04:10 +00:00
|
|
|
WSI_GET_CB(EndCommandBuffer);
|
|
|
|
WSI_GET_CB(FreeMemory);
|
|
|
|
WSI_GET_CB(FreeCommandBuffers);
|
|
|
|
WSI_GET_CB(GetBufferMemoryRequirements);
|
2018-10-01 22:14:24 +01:00
|
|
|
WSI_GET_CB(GetImageDrmFormatModifierPropertiesEXT);
|
2017-11-16 03:04:10 +00:00
|
|
|
WSI_GET_CB(GetImageMemoryRequirements);
|
2017-11-16 06:30:20 +00:00
|
|
|
WSI_GET_CB(GetImageSubresourceLayout);
|
2020-06-19 07:37:51 +01:00
|
|
|
if (!wsi->sw)
|
|
|
|
WSI_GET_CB(GetMemoryFdKHR);
|
2017-11-16 20:38:26 +00:00
|
|
|
WSI_GET_CB(GetPhysicalDeviceFormatProperties);
|
2018-02-09 23:43:27 +00:00
|
|
|
WSI_GET_CB(GetPhysicalDeviceFormatProperties2KHR);
|
2018-10-01 22:00:32 +01:00
|
|
|
WSI_GET_CB(GetPhysicalDeviceImageFormatProperties2);
|
2017-11-16 01:52:39 +00:00
|
|
|
WSI_GET_CB(ResetFences);
|
2017-11-16 03:04:10 +00:00
|
|
|
WSI_GET_CB(QueueSubmit);
|
2017-11-16 01:52:39 +00:00
|
|
|
WSI_GET_CB(WaitForFences);
|
2020-06-19 07:37:51 +01:00
|
|
|
WSI_GET_CB(MapMemory);
|
|
|
|
WSI_GET_CB(UnmapMemory);
|
2017-11-16 03:04:10 +00:00
|
|
|
#undef WSI_GET_CB
|
2017-11-16 20:49:27 +00:00
|
|
|
|
|
|
|
#ifdef VK_USE_PLATFORM_XCB_KHR
|
2019-08-29 23:49:29 +01:00
|
|
|
result = wsi_x11_init_wsi(wsi, alloc, dri_options);
|
2017-11-16 20:49:27 +00:00
|
|
|
if (result != VK_SUCCESS)
|
2018-02-26 13:34:54 +00:00
|
|
|
goto fail;
|
2017-11-16 20:49:27 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
|
|
|
result = wsi_wl_init_wsi(wsi, alloc, pdevice);
|
2018-02-26 13:34:54 +00:00
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
goto fail;
|
2017-11-16 20:49:27 +00:00
|
|
|
#endif
|
|
|
|
|
2020-11-09 21:51:01 +00:00
|
|
|
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
|
|
|
result = wsi_win32_init_wsi(wsi, alloc, pdevice);
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
goto fail;
|
|
|
|
#endif
|
|
|
|
|
vulkan: Add KHR_display extension using DRM [v10]
This adds support for the KHR_display extension support to the vulkan
WSI layer. Driver support will be added separately.
v2:
* fix double ;; in wsi_common_display.c
* Move mode list from wsi_display to wsi_display_connector
* Fix scope for wsi_display_mode andwsi_display_connector
allocs
* Switch all allocations to vk_zalloc instead of vk_alloc.
* Fix DRM failure in
wsi_display_get_physical_device_display_properties
When DRM fails, or when we don't have a master fd
(presumably due to application errors), just return 0
properties from this function, which is at least a valid
response.
* Use vk_outarray for all property queries
This is a bit less error-prone than open-coding the same
stuff.
* Remove VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR from surface caps
Until we have multi-plane support, we shouldn't pretend to
have any multi-plane semantics, even if undefined.
Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
* Simplify addition of VK_USE_PLATFORM_DISPLAY_KHR to
vulkan_wsi_args
Suggested-by: Eric Engestrom <eric.engestrom@imgtec.com>
v3:
Add separate 'display_fd' and 'render_fd' arguments to
wsi_device_init API. This allows drivers to use different FDs
for the different aspects of the device.
Use largest mode as display size when no preferred mode.
If the display doesn't provide a preferred mode, we'll assume
that the largest supported mode is the "physical size" of the
device and report that.
v4:
Make wsi_image_state enumeration values uppercase.
Follow more common mesa conventions.
Remove 'render_fd' from wsi_device_init API. The
wsi_common_display code doesn't use this fd at all, so stop
passing it in. This avoids any potential confusion over which
fd to use when creating display-relative object handles.
Remove call to wsi_create_prime_image which would never have
been reached as the necessary condition (use_prime_blit) is
never set.
whitespace cleanups in wsi_common_display.c
Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
Add depth/bpp info to available surface formats. Instead of
hard-coding depth 24 bpp 32 in the drmModeAddFB call, use the
requested format to find suitable values.
Destroy kernel buffers and FBs when swapchain is destroyed. We
were leaking both of these kernel objects across swapchain
destruction.
Note that wsi_display_wait_for_event waits for anything to
happen. wsi_display_wait_for_event is simply a yield so that
the caller can then check to see if the desired state change
has occurred.
Record swapchain failures in chain for later return. If some
asynchronous swapchain activity fails, we need to tell the
application eventually. Record the failure in the swapchain
and report it at the next acquire_next_image or queue_present
call.
Fix error returns from wsi_display_setup_connector. If a
malloc failed, then the result should be
VK_ERROR_OUT_OF_HOST_MEMORY. Otherwise, the associated ioctl
failed and we're either VT switched away, or our lease has
been revoked, in which case we should return
VK_ERROR_OUT_OF_DATE_KHR.
Make sure both sides of if/else brace use matches
Note that we assume drmModeSetCrtc is synchronous. Add a
comment explaining why we can idle any previous displayed
image as soon as the mode set returns.
Note that EACCES from drmModePageFlip means VT inactive. When
vt switched away drmModePageFlip returns EACCES. Poll once a
second waiting until we get some other return value back.
Clean up after alloc failure in
wsi_display_surface_create_swapchain. Destroy any created
images, free the swapchain.
Remove physical_device from wsi_display_init_wsi. We never
need this value, so remove it from the API and from the
internal wsi_display structure.
Use drmModeAddFB2 in wsi_display_image_init. This takes a drm
format instead of depth/bpp, which provides more control over
the format of the data.
v5:
Set the 'currentStackIndex' member of the
VkDisplayPlanePropertiesKHR record to zero, instead of
indexing across all displays. This value is the stack depth of
the plane within an individual display, and as the current
code supports only a single plane per display, should be set
to zero for all elements
Discovered-by: David Mao <David.Mao@amd.com>
v6:
Remove 'platform_display' bits from the build and use the
existing 'platform_drm' instead.
v7:
Ensure VK_ICD_WSI_PLATFORM_MAX is large enough by
setting to VK_ICD_WSI_PLATFORM_DISPLAY + 1
v8:
Simplify wsi_device_init failure from wsi_display_init_wsi
by using the same pattern as the other wsi layers.
Adopt Jason Ekstrand's white space and variable declaration
suggestions. Declare variables at first use, eliminate extra
whitespace between types and names, add list iterator helpers,
switch to lower-case list_ macros.
Respond to Jason's April 8 review:
* Create a function to convert relative to absolute timeouts
to catch overflow issues in one place
* use VK_NULL_HANDLE to clear prop->currentDisplay
* Get rid of available_present_modes array.
* return OUT_OF_DATE_KHR when display_queue_next called after
display has been released.
* Make errors from mode setting fatal in display_queue_next
* Remove duplicate pthread_mutex_init call
* Add wsi_init_pthread_cond_monotonic helper function to
isolate pthread error handling from wsi_display_init_wsi
Suggested-by: Jason Ekstrand <jason.ekstrand@intel.com>
v9:
Fix vscan handling by using MAX2(vscan, 1) everywhere. Vscan
can be zero anywhere, which is treated the same as 1.
Suggested-by: Jason Ekstrand <jason.ekstrand@intel.com>
v10:
Respond to Vulkan CTS failures.
1. Initialize planeReorderPossible in display_properties code
2. Only report connected displays in
get_display_plane_supported_displays
3. Return VK_ERROR_OUT_OF_HOST_MEMORY when pthread cond
initialization fails.
Signed-off-by: Jason Ekstrand <jason.ekstrand@intel.com>
4. Add vkCreateDisplayModeKHR. This doesn't actually create
new modes, it only looks to see if the requested parameters
matches an existing mode and returns that.
Suggested-by: Jason Ekstrand <jason.ekstrand@intel.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Signed-off-by: Keith Packard <keithp@keithp.com>
2018-02-07 18:31:44 +00:00
|
|
|
#ifdef VK_USE_PLATFORM_DISPLAY_KHR
|
|
|
|
result = wsi_display_init_wsi(wsi, alloc, display_fd);
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
goto fail;
|
|
|
|
#endif
|
|
|
|
|
2019-04-09 14:30:05 +01:00
|
|
|
present_mode = getenv("MESA_VK_WSI_PRESENT_MODE");
|
|
|
|
if (present_mode) {
|
|
|
|
if (!strcmp(present_mode, "fifo")) {
|
|
|
|
wsi->override_present_mode = VK_PRESENT_MODE_FIFO_KHR;
|
2020-09-09 22:03:11 +01:00
|
|
|
} else if (!strcmp(present_mode, "relaxed")) {
|
|
|
|
wsi->override_present_mode = VK_PRESENT_MODE_FIFO_RELAXED_KHR;
|
2019-04-09 14:30:05 +01:00
|
|
|
} else if (!strcmp(present_mode, "mailbox")) {
|
|
|
|
wsi->override_present_mode = VK_PRESENT_MODE_MAILBOX_KHR;
|
|
|
|
} else if (!strcmp(present_mode, "immediate")) {
|
|
|
|
wsi->override_present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR;
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "Invalid MESA_VK_WSI_PRESENT_MODE value!\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-17 00:30:49 +01:00
|
|
|
if (dri_options) {
|
|
|
|
if (driCheckOption(dri_options, "adaptive_sync", DRI_BOOL))
|
|
|
|
wsi->enable_adaptive_sync = driQueryOptionb(dri_options,
|
|
|
|
"adaptive_sync");
|
2020-01-10 19:16:25 +00:00
|
|
|
|
|
|
|
if (driCheckOption(dri_options, "vk_wsi_force_bgra8_unorm_first", DRI_BOOL)) {
|
|
|
|
wsi->force_bgra8_unorm_first =
|
|
|
|
driQueryOptionb(dri_options, "vk_wsi_force_bgra8_unorm_first");
|
|
|
|
}
|
2019-04-17 00:30:49 +01:00
|
|
|
}
|
|
|
|
|
2017-11-16 20:49:27 +00:00
|
|
|
return VK_SUCCESS;
|
2019-12-17 03:58:39 +00:00
|
|
|
#if defined(VK_USE_PLATFORM_XCB_KHR) || \
|
|
|
|
defined(VK_USE_PLATFORM_WAYLAND_KHR) || \
|
2020-11-09 21:51:01 +00:00
|
|
|
defined(VK_USE_PLATFORM_WIN32_KHR) || \
|
2019-12-17 03:58:39 +00:00
|
|
|
defined(VK_USE_PLATFORM_DISPLAY_KHR)
|
2018-02-26 13:34:54 +00:00
|
|
|
fail:
|
|
|
|
wsi_device_finish(wsi, alloc);
|
|
|
|
return result;
|
2019-12-17 03:58:39 +00:00
|
|
|
#endif
|
2017-11-16 20:49:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
wsi_device_finish(struct wsi_device *wsi,
|
|
|
|
const VkAllocationCallbacks *alloc)
|
|
|
|
{
|
vulkan: Add KHR_display extension using DRM [v10]
This adds support for the KHR_display extension support to the vulkan
WSI layer. Driver support will be added separately.
v2:
* fix double ;; in wsi_common_display.c
* Move mode list from wsi_display to wsi_display_connector
* Fix scope for wsi_display_mode andwsi_display_connector
allocs
* Switch all allocations to vk_zalloc instead of vk_alloc.
* Fix DRM failure in
wsi_display_get_physical_device_display_properties
When DRM fails, or when we don't have a master fd
(presumably due to application errors), just return 0
properties from this function, which is at least a valid
response.
* Use vk_outarray for all property queries
This is a bit less error-prone than open-coding the same
stuff.
* Remove VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR from surface caps
Until we have multi-plane support, we shouldn't pretend to
have any multi-plane semantics, even if undefined.
Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
* Simplify addition of VK_USE_PLATFORM_DISPLAY_KHR to
vulkan_wsi_args
Suggested-by: Eric Engestrom <eric.engestrom@imgtec.com>
v3:
Add separate 'display_fd' and 'render_fd' arguments to
wsi_device_init API. This allows drivers to use different FDs
for the different aspects of the device.
Use largest mode as display size when no preferred mode.
If the display doesn't provide a preferred mode, we'll assume
that the largest supported mode is the "physical size" of the
device and report that.
v4:
Make wsi_image_state enumeration values uppercase.
Follow more common mesa conventions.
Remove 'render_fd' from wsi_device_init API. The
wsi_common_display code doesn't use this fd at all, so stop
passing it in. This avoids any potential confusion over which
fd to use when creating display-relative object handles.
Remove call to wsi_create_prime_image which would never have
been reached as the necessary condition (use_prime_blit) is
never set.
whitespace cleanups in wsi_common_display.c
Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
Add depth/bpp info to available surface formats. Instead of
hard-coding depth 24 bpp 32 in the drmModeAddFB call, use the
requested format to find suitable values.
Destroy kernel buffers and FBs when swapchain is destroyed. We
were leaking both of these kernel objects across swapchain
destruction.
Note that wsi_display_wait_for_event waits for anything to
happen. wsi_display_wait_for_event is simply a yield so that
the caller can then check to see if the desired state change
has occurred.
Record swapchain failures in chain for later return. If some
asynchronous swapchain activity fails, we need to tell the
application eventually. Record the failure in the swapchain
and report it at the next acquire_next_image or queue_present
call.
Fix error returns from wsi_display_setup_connector. If a
malloc failed, then the result should be
VK_ERROR_OUT_OF_HOST_MEMORY. Otherwise, the associated ioctl
failed and we're either VT switched away, or our lease has
been revoked, in which case we should return
VK_ERROR_OUT_OF_DATE_KHR.
Make sure both sides of if/else brace use matches
Note that we assume drmModeSetCrtc is synchronous. Add a
comment explaining why we can idle any previous displayed
image as soon as the mode set returns.
Note that EACCES from drmModePageFlip means VT inactive. When
vt switched away drmModePageFlip returns EACCES. Poll once a
second waiting until we get some other return value back.
Clean up after alloc failure in
wsi_display_surface_create_swapchain. Destroy any created
images, free the swapchain.
Remove physical_device from wsi_display_init_wsi. We never
need this value, so remove it from the API and from the
internal wsi_display structure.
Use drmModeAddFB2 in wsi_display_image_init. This takes a drm
format instead of depth/bpp, which provides more control over
the format of the data.
v5:
Set the 'currentStackIndex' member of the
VkDisplayPlanePropertiesKHR record to zero, instead of
indexing across all displays. This value is the stack depth of
the plane within an individual display, and as the current
code supports only a single plane per display, should be set
to zero for all elements
Discovered-by: David Mao <David.Mao@amd.com>
v6:
Remove 'platform_display' bits from the build and use the
existing 'platform_drm' instead.
v7:
Ensure VK_ICD_WSI_PLATFORM_MAX is large enough by
setting to VK_ICD_WSI_PLATFORM_DISPLAY + 1
v8:
Simplify wsi_device_init failure from wsi_display_init_wsi
by using the same pattern as the other wsi layers.
Adopt Jason Ekstrand's white space and variable declaration
suggestions. Declare variables at first use, eliminate extra
whitespace between types and names, add list iterator helpers,
switch to lower-case list_ macros.
Respond to Jason's April 8 review:
* Create a function to convert relative to absolute timeouts
to catch overflow issues in one place
* use VK_NULL_HANDLE to clear prop->currentDisplay
* Get rid of available_present_modes array.
* return OUT_OF_DATE_KHR when display_queue_next called after
display has been released.
* Make errors from mode setting fatal in display_queue_next
* Remove duplicate pthread_mutex_init call
* Add wsi_init_pthread_cond_monotonic helper function to
isolate pthread error handling from wsi_display_init_wsi
Suggested-by: Jason Ekstrand <jason.ekstrand@intel.com>
v9:
Fix vscan handling by using MAX2(vscan, 1) everywhere. Vscan
can be zero anywhere, which is treated the same as 1.
Suggested-by: Jason Ekstrand <jason.ekstrand@intel.com>
v10:
Respond to Vulkan CTS failures.
1. Initialize planeReorderPossible in display_properties code
2. Only report connected displays in
get_display_plane_supported_displays
3. Return VK_ERROR_OUT_OF_HOST_MEMORY when pthread cond
initialization fails.
Signed-off-by: Jason Ekstrand <jason.ekstrand@intel.com>
4. Add vkCreateDisplayModeKHR. This doesn't actually create
new modes, it only looks to see if the requested parameters
matches an existing mode and returns that.
Suggested-by: Jason Ekstrand <jason.ekstrand@intel.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Signed-off-by: Keith Packard <keithp@keithp.com>
2018-02-07 18:31:44 +00:00
|
|
|
#ifdef VK_USE_PLATFORM_DISPLAY_KHR
|
|
|
|
wsi_display_finish_wsi(wsi, alloc);
|
|
|
|
#endif
|
2017-11-16 20:49:27 +00:00
|
|
|
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
|
|
|
wsi_wl_finish_wsi(wsi, alloc);
|
|
|
|
#endif
|
2020-11-09 21:51:01 +00:00
|
|
|
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
|
|
|
wsi_win32_finish_wsi(wsi, alloc);
|
|
|
|
#endif
|
2017-11-16 20:49:27 +00:00
|
|
|
#ifdef VK_USE_PLATFORM_XCB_KHR
|
|
|
|
wsi_x11_finish_wsi(wsi, alloc);
|
|
|
|
#endif
|
2017-11-16 02:50:44 +00:00
|
|
|
}
|
2017-11-16 04:08:53 +00:00
|
|
|
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
VKAPI_ATTR void VKAPI_CALL
|
|
|
|
wsi_DestroySurfaceKHR(VkInstance _instance,
|
|
|
|
VkSurfaceKHR _surface,
|
|
|
|
const VkAllocationCallbacks *pAllocator)
|
|
|
|
{
|
|
|
|
VK_FROM_HANDLE(vk_instance, instance, _instance);
|
|
|
|
ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
|
|
|
|
|
|
|
|
if (!surface)
|
|
|
|
return;
|
|
|
|
|
|
|
|
vk_free2(&instance->alloc, pAllocator, surface);
|
|
|
|
}
|
|
|
|
|
2021-10-14 12:43:00 +01:00
|
|
|
void
|
|
|
|
wsi_device_setup_syncobj_fd(struct wsi_device *wsi_device,
|
|
|
|
int fd)
|
|
|
|
{
|
|
|
|
#ifdef VK_USE_PLATFORM_DISPLAY_KHR
|
|
|
|
wsi_display_setup_syncobj_fd(wsi_device, fd);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2017-11-16 04:08:53 +00:00
|
|
|
VkResult
|
|
|
|
wsi_swapchain_init(const struct wsi_device *wsi,
|
|
|
|
struct wsi_swapchain *chain,
|
|
|
|
VkDevice device,
|
2017-11-16 03:04:10 +00:00
|
|
|
const VkSwapchainCreateInfoKHR *pCreateInfo,
|
2022-01-07 13:49:30 +00:00
|
|
|
const VkAllocationCallbacks *pAllocator,
|
2022-02-03 09:57:16 +00:00
|
|
|
bool use_buffer_blit)
|
2017-11-16 04:08:53 +00:00
|
|
|
{
|
2017-11-16 03:04:10 +00:00
|
|
|
VkResult result;
|
|
|
|
|
2017-11-16 04:08:53 +00:00
|
|
|
memset(chain, 0, sizeof(*chain));
|
|
|
|
|
2020-04-21 23:00:39 +01:00
|
|
|
vk_object_base_init(NULL, &chain->base, VK_OBJECT_TYPE_SWAPCHAIN_KHR);
|
|
|
|
|
2017-11-16 04:08:53 +00:00
|
|
|
chain->wsi = wsi;
|
|
|
|
chain->device = device;
|
|
|
|
chain->alloc = *pAllocator;
|
2022-02-03 09:57:16 +00:00
|
|
|
chain->use_buffer_blit = use_buffer_blit;
|
|
|
|
chain->buffer_blit_queue = VK_NULL_HANDLE;
|
|
|
|
if (use_buffer_blit && wsi->get_buffer_blit_queue)
|
|
|
|
chain->buffer_blit_queue = wsi->get_buffer_blit_queue(device);
|
2021-12-08 13:05:15 +00:00
|
|
|
|
2022-02-03 09:57:16 +00:00
|
|
|
int cmd_pools_count = chain->buffer_blit_queue != VK_NULL_HANDLE ? 1 : wsi->queue_family_count;
|
2017-11-16 04:08:53 +00:00
|
|
|
|
2017-11-16 03:04:10 +00:00
|
|
|
chain->cmd_pools =
|
2021-12-08 13:05:15 +00:00
|
|
|
vk_zalloc(pAllocator, sizeof(VkCommandPool) * cmd_pools_count, 8,
|
2017-11-16 03:04:10 +00:00
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
|
|
|
if (!chain->cmd_pools)
|
|
|
|
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
|
|
|
|
2021-12-08 13:05:15 +00:00
|
|
|
for (uint32_t i = 0; i < cmd_pools_count; i++) {
|
|
|
|
int queue_family_index = i;
|
|
|
|
|
2022-02-03 09:57:16 +00:00
|
|
|
if (chain->buffer_blit_queue != VK_NULL_HANDLE) {
|
|
|
|
VK_FROM_HANDLE(vk_queue, queue, chain->buffer_blit_queue);
|
2021-12-08 13:05:15 +00:00
|
|
|
queue_family_index = queue->queue_family_index;
|
|
|
|
}
|
2017-11-16 03:04:10 +00:00
|
|
|
const VkCommandPoolCreateInfo cmd_pool_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
|
|
|
.pNext = NULL,
|
|
|
|
.flags = 0,
|
2021-12-08 13:05:15 +00:00
|
|
|
.queueFamilyIndex = queue_family_index,
|
2017-11-16 03:04:10 +00:00
|
|
|
};
|
|
|
|
result = wsi->CreateCommandPool(device, &cmd_pool_info, &chain->alloc,
|
|
|
|
&chain->cmd_pools[i]);
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
2017-11-16 04:08:53 +00:00
|
|
|
return VK_SUCCESS;
|
2017-11-16 03:04:10 +00:00
|
|
|
|
|
|
|
fail:
|
|
|
|
wsi_swapchain_finish(chain);
|
|
|
|
return result;
|
2017-11-16 04:08:53 +00:00
|
|
|
}
|
|
|
|
|
2019-04-09 14:30:05 +01:00
|
|
|
static bool
|
|
|
|
wsi_swapchain_is_present_mode_supported(struct wsi_device *wsi,
|
|
|
|
const VkSwapchainCreateInfoKHR *pCreateInfo,
|
|
|
|
VkPresentModeKHR mode)
|
|
|
|
{
|
|
|
|
ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pCreateInfo->surface);
|
|
|
|
struct wsi_interface *iface = wsi->wsi[surface->platform];
|
|
|
|
VkPresentModeKHR *present_modes;
|
|
|
|
uint32_t present_mode_count;
|
|
|
|
bool supported = false;
|
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
result = iface->get_present_modes(surface, &present_mode_count, NULL);
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
return supported;
|
|
|
|
|
|
|
|
present_modes = malloc(present_mode_count * sizeof(*present_modes));
|
|
|
|
if (!present_modes)
|
|
|
|
return supported;
|
|
|
|
|
|
|
|
result = iface->get_present_modes(surface, &present_mode_count,
|
|
|
|
present_modes);
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < present_mode_count; i++) {
|
|
|
|
if (present_modes[i] == mode) {
|
|
|
|
supported = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fail:
|
|
|
|
free(present_modes);
|
|
|
|
return supported;
|
|
|
|
}
|
|
|
|
|
|
|
|
enum VkPresentModeKHR
|
|
|
|
wsi_swapchain_get_present_mode(struct wsi_device *wsi,
|
|
|
|
const VkSwapchainCreateInfoKHR *pCreateInfo)
|
|
|
|
{
|
|
|
|
if (wsi->override_present_mode == VK_PRESENT_MODE_MAX_ENUM_KHR)
|
|
|
|
return pCreateInfo->presentMode;
|
|
|
|
|
|
|
|
if (!wsi_swapchain_is_present_mode_supported(wsi, pCreateInfo,
|
|
|
|
wsi->override_present_mode)) {
|
|
|
|
fprintf(stderr, "Unsupported MESA_VK_WSI_PRESENT_MODE value!\n");
|
|
|
|
return pCreateInfo->presentMode;
|
|
|
|
}
|
|
|
|
|
|
|
|
return wsi->override_present_mode;
|
|
|
|
}
|
|
|
|
|
2017-11-16 04:08:53 +00:00
|
|
|
void
|
|
|
|
wsi_swapchain_finish(struct wsi_swapchain *chain)
|
|
|
|
{
|
2019-05-20 01:51:51 +01:00
|
|
|
if (chain->fences) {
|
|
|
|
for (unsigned i = 0; i < chain->image_count; i++)
|
|
|
|
chain->wsi->DestroyFence(chain->device, chain->fences[i], &chain->alloc);
|
|
|
|
|
|
|
|
vk_free(&chain->alloc, chain->fences);
|
|
|
|
}
|
2022-02-03 09:57:16 +00:00
|
|
|
if (chain->buffer_blit_semaphores) {
|
2021-12-08 13:05:15 +00:00
|
|
|
for (unsigned i = 0; i < chain->image_count; i++)
|
2022-02-03 09:57:16 +00:00
|
|
|
chain->wsi->DestroySemaphore(chain->device, chain->buffer_blit_semaphores[i], &chain->alloc);
|
2021-12-08 13:05:15 +00:00
|
|
|
|
2022-02-03 09:57:16 +00:00
|
|
|
vk_free(&chain->alloc, chain->buffer_blit_semaphores);
|
2021-12-08 13:05:15 +00:00
|
|
|
}
|
2017-11-16 02:02:04 +00:00
|
|
|
|
2022-02-03 09:57:16 +00:00
|
|
|
int cmd_pools_count = chain->buffer_blit_queue != VK_NULL_HANDLE ?
|
2021-12-08 13:05:15 +00:00
|
|
|
1 : chain->wsi->queue_family_count;
|
|
|
|
for (uint32_t i = 0; i < cmd_pools_count; i++) {
|
2017-11-16 03:04:10 +00:00
|
|
|
chain->wsi->DestroyCommandPool(chain->device, chain->cmd_pools[i],
|
|
|
|
&chain->alloc);
|
|
|
|
}
|
2017-12-27 23:45:07 +00:00
|
|
|
vk_free(&chain->alloc, chain->cmd_pools);
|
2020-04-21 23:00:39 +01:00
|
|
|
|
|
|
|
vk_object_base_finish(&chain->base);
|
2017-11-16 03:04:10 +00:00
|
|
|
}
|
|
|
|
|
2021-07-22 23:50:38 +01:00
|
|
|
VkResult
|
|
|
|
wsi_configure_image(const struct wsi_swapchain *chain,
|
|
|
|
const VkSwapchainCreateInfoKHR *pCreateInfo,
|
|
|
|
VkExternalMemoryHandleTypeFlags handle_types,
|
|
|
|
struct wsi_image_info *info)
|
|
|
|
{
|
|
|
|
memset(info, 0, sizeof(*info));
|
2022-02-21 05:43:39 +00:00
|
|
|
uint32_t *queue_family_indices;
|
|
|
|
|
|
|
|
if (pCreateInfo->imageSharingMode == VK_SHARING_MODE_CONCURRENT) {
|
|
|
|
queue_family_indices =
|
|
|
|
vk_alloc(&chain->alloc,
|
|
|
|
sizeof(*queue_family_indices) *
|
|
|
|
pCreateInfo->queueFamilyIndexCount,
|
|
|
|
8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
|
|
|
if (!queue_family_indices)
|
|
|
|
goto err_oom;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < pCreateInfo->queueFamilyIndexCount; i++)
|
|
|
|
queue_family_indices[i] = pCreateInfo->pQueueFamilyIndices[i];
|
|
|
|
} else {
|
|
|
|
queue_family_indices = NULL;
|
|
|
|
}
|
2021-07-22 23:50:38 +01:00
|
|
|
|
|
|
|
info->create = (VkImageCreateInfo) {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
2021-08-09 16:23:18 +01:00
|
|
|
.flags = VK_IMAGE_CREATE_ALIAS_BIT,
|
2021-07-22 23:50:38 +01:00
|
|
|
.imageType = VK_IMAGE_TYPE_2D,
|
|
|
|
.format = pCreateInfo->imageFormat,
|
|
|
|
.extent = {
|
|
|
|
.width = pCreateInfo->imageExtent.width,
|
|
|
|
.height = pCreateInfo->imageExtent.height,
|
|
|
|
.depth = 1,
|
|
|
|
},
|
|
|
|
.mipLevels = 1,
|
|
|
|
.arrayLayers = 1,
|
|
|
|
.samples = VK_SAMPLE_COUNT_1_BIT,
|
|
|
|
.tiling = VK_IMAGE_TILING_OPTIMAL,
|
|
|
|
.usage = pCreateInfo->imageUsage,
|
|
|
|
.sharingMode = pCreateInfo->imageSharingMode,
|
|
|
|
.queueFamilyIndexCount = pCreateInfo->queueFamilyIndexCount,
|
|
|
|
.pQueueFamilyIndices = queue_family_indices,
|
|
|
|
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
|
|
|
};
|
|
|
|
|
|
|
|
if (handle_types != 0) {
|
|
|
|
info->ext_mem = (VkExternalMemoryImageCreateInfo) {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
|
|
|
|
.handleTypes = handle_types,
|
|
|
|
};
|
|
|
|
__vk_append_struct(&info->create, &info->ext_mem);
|
|
|
|
}
|
|
|
|
|
|
|
|
info->wsi = (struct wsi_image_create_info) {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO_MESA,
|
|
|
|
};
|
|
|
|
__vk_append_struct(&info->create, &info->wsi);
|
|
|
|
|
|
|
|
if (pCreateInfo->flags & VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR) {
|
|
|
|
info->create.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT |
|
|
|
|
VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR;
|
|
|
|
|
|
|
|
const VkImageFormatListCreateInfoKHR *format_list_in =
|
|
|
|
vk_find_struct_const(pCreateInfo->pNext,
|
|
|
|
IMAGE_FORMAT_LIST_CREATE_INFO_KHR);
|
|
|
|
|
|
|
|
assume(format_list_in && format_list_in->viewFormatCount > 0);
|
|
|
|
|
|
|
|
const uint32_t view_format_count = format_list_in->viewFormatCount;
|
|
|
|
VkFormat *view_formats =
|
|
|
|
vk_alloc(&chain->alloc, sizeof(VkFormat) * view_format_count,
|
|
|
|
8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
|
|
|
if (!view_formats)
|
|
|
|
goto err_oom;
|
|
|
|
|
|
|
|
ASSERTED bool format_found = false;
|
|
|
|
for (uint32_t i = 0; i < format_list_in->viewFormatCount; i++) {
|
|
|
|
if (pCreateInfo->imageFormat == format_list_in->pViewFormats[i])
|
|
|
|
format_found = true;
|
|
|
|
view_formats[i] = format_list_in->pViewFormats[i];
|
|
|
|
}
|
|
|
|
assert(format_found);
|
|
|
|
|
|
|
|
info->format_list = (VkImageFormatListCreateInfoKHR) {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR,
|
|
|
|
.viewFormatCount = view_format_count,
|
|
|
|
.pViewFormats = view_formats,
|
|
|
|
};
|
|
|
|
__vk_append_struct(&info->create, &info->format_list);
|
|
|
|
}
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
|
|
err_oom:
|
|
|
|
wsi_destroy_image_info(chain, info);
|
|
|
|
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
wsi_destroy_image_info(const struct wsi_swapchain *chain,
|
|
|
|
struct wsi_image_info *info)
|
|
|
|
{
|
|
|
|
vk_free(&chain->alloc, (void *)info->create.pQueueFamilyIndices);
|
|
|
|
vk_free(&chain->alloc, (void *)info->format_list.pViewFormats);
|
|
|
|
vk_free(&chain->alloc, (void *)info->drm_mod_list.pDrmFormatModifiers);
|
|
|
|
vk_free(&chain->alloc, info->modifier_props);
|
|
|
|
}
|
|
|
|
|
2021-07-23 04:31:57 +01:00
|
|
|
VkResult
|
|
|
|
wsi_create_image(const struct wsi_swapchain *chain,
|
|
|
|
const struct wsi_image_info *info,
|
|
|
|
struct wsi_image *image)
|
|
|
|
{
|
|
|
|
const struct wsi_device *wsi = chain->wsi;
|
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
memset(image, 0, sizeof(*image));
|
|
|
|
for (int i = 0; i < ARRAY_SIZE(image->fds); i++)
|
|
|
|
image->fds[i] = -1;
|
|
|
|
|
|
|
|
result = wsi->CreateImage(chain->device, &info->create,
|
|
|
|
&chain->alloc, &image->image);
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
result = info->create_mem(chain, info, image);
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
result = wsi->BindImageMemory(chain->device, image->image,
|
|
|
|
image->memory, 0);
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
goto fail;
|
|
|
|
|
2021-07-23 00:24:02 +01:00
|
|
|
if (info->finish_create) {
|
|
|
|
result = info->finish_create(chain, info, image);
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
2021-07-23 04:31:57 +01:00
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
|
|
fail:
|
|
|
|
wsi_destroy_image(chain, image);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-11-16 03:04:10 +00:00
|
|
|
void
|
2017-11-16 06:30:20 +00:00
|
|
|
wsi_destroy_image(const struct wsi_swapchain *chain,
|
|
|
|
struct wsi_image *image)
|
2017-11-16 03:04:10 +00:00
|
|
|
{
|
|
|
|
const struct wsi_device *wsi = chain->wsi;
|
|
|
|
|
2022-02-03 09:57:16 +00:00
|
|
|
if (image->buffer.blit_cmd_buffers) {
|
2017-11-16 03:04:10 +00:00
|
|
|
for (uint32_t i = 0; i < wsi->queue_family_count; i++) {
|
|
|
|
wsi->FreeCommandBuffers(chain->device, chain->cmd_pools[i],
|
2022-02-03 09:57:16 +00:00
|
|
|
1, &image->buffer.blit_cmd_buffers[i]);
|
2017-11-16 03:04:10 +00:00
|
|
|
}
|
2022-02-03 09:57:16 +00:00
|
|
|
vk_free(&chain->alloc, image->buffer.blit_cmd_buffers);
|
2017-11-16 03:04:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
wsi->FreeMemory(chain->device, image->memory, &chain->alloc);
|
|
|
|
wsi->DestroyImage(chain->device, image->image, &chain->alloc);
|
2022-02-03 09:57:16 +00:00
|
|
|
wsi->FreeMemory(chain->device, image->buffer.memory, &chain->alloc);
|
|
|
|
wsi->DestroyBuffer(chain->device, image->buffer.buffer, &chain->alloc);
|
2017-11-16 03:04:10 +00:00
|
|
|
}
|
|
|
|
|
2021-10-06 18:42:18 +01:00
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL
|
|
|
|
wsi_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,
|
|
|
|
uint32_t queueFamilyIndex,
|
|
|
|
VkSurfaceKHR _surface,
|
|
|
|
VkBool32 *pSupported)
|
2017-11-16 20:26:26 +00:00
|
|
|
{
|
2021-10-06 18:42:18 +01:00
|
|
|
VK_FROM_HANDLE(vk_physical_device, device, physicalDevice);
|
2017-11-16 20:26:26 +00:00
|
|
|
ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
|
2021-10-06 18:42:18 +01:00
|
|
|
struct wsi_device *wsi_device = device->wsi_device;
|
2017-11-16 20:26:26 +00:00
|
|
|
struct wsi_interface *iface = wsi_device->wsi[surface->platform];
|
|
|
|
|
2018-10-17 20:35:16 +01:00
|
|
|
return iface->get_support(surface, wsi_device,
|
2018-10-18 16:08:32 +01:00
|
|
|
queueFamilyIndex, pSupported);
|
2017-11-16 20:26:26 +00:00
|
|
|
}
|
|
|
|
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL
|
2021-10-06 18:42:18 +01:00
|
|
|
wsi_GetPhysicalDeviceSurfaceCapabilitiesKHR(
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
VkSurfaceKHR _surface,
|
|
|
|
VkSurfaceCapabilitiesKHR *pSurfaceCapabilities)
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
{
|
|
|
|
VK_FROM_HANDLE(vk_physical_device, device, physicalDevice);
|
2017-11-16 20:26:26 +00:00
|
|
|
ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
|
2021-10-06 18:42:18 +01:00
|
|
|
struct wsi_device *wsi_device = device->wsi_device;
|
2017-11-16 20:26:26 +00:00
|
|
|
struct wsi_interface *iface = wsi_device->wsi[surface->platform];
|
|
|
|
|
2018-06-16 18:27:40 +01:00
|
|
|
VkSurfaceCapabilities2KHR caps2 = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR,
|
|
|
|
};
|
|
|
|
|
2018-11-25 11:23:26 +00:00
|
|
|
VkResult result = iface->get_capabilities2(surface, wsi_device, NULL, &caps2);
|
2018-06-16 18:27:40 +01:00
|
|
|
|
|
|
|
if (result == VK_SUCCESS)
|
|
|
|
*pSurfaceCapabilities = caps2.surfaceCapabilities;
|
|
|
|
|
|
|
|
return result;
|
2017-11-16 20:26:26 +00:00
|
|
|
}
|
|
|
|
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL
|
2021-10-06 18:42:18 +01:00
|
|
|
wsi_GetPhysicalDeviceSurfaceCapabilities2KHR(
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
VkPhysicalDevice physicalDevice,
|
2021-10-06 18:42:18 +01:00
|
|
|
const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
|
|
|
|
VkSurfaceCapabilities2KHR *pSurfaceCapabilities)
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
{
|
|
|
|
VK_FROM_HANDLE(vk_physical_device, device, physicalDevice);
|
2017-11-16 20:26:26 +00:00
|
|
|
ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pSurfaceInfo->surface);
|
2021-10-06 18:42:18 +01:00
|
|
|
struct wsi_device *wsi_device = device->wsi_device;
|
2017-11-16 20:26:26 +00:00
|
|
|
struct wsi_interface *iface = wsi_device->wsi[surface->platform];
|
|
|
|
|
2018-11-25 11:23:26 +00:00
|
|
|
return iface->get_capabilities2(surface, wsi_device, pSurfaceInfo->pNext,
|
2017-11-16 20:26:26 +00:00
|
|
|
pSurfaceCapabilities);
|
|
|
|
}
|
|
|
|
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL
|
2021-10-06 18:42:18 +01:00
|
|
|
wsi_GetPhysicalDeviceSurfaceCapabilities2EXT(
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
VkPhysicalDevice physicalDevice,
|
2018-06-16 18:44:11 +01:00
|
|
|
VkSurfaceKHR _surface,
|
|
|
|
VkSurfaceCapabilities2EXT *pSurfaceCapabilities)
|
|
|
|
{
|
2021-10-06 18:42:18 +01:00
|
|
|
VK_FROM_HANDLE(vk_physical_device, device, physicalDevice);
|
2018-06-16 18:44:11 +01:00
|
|
|
ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
|
2021-10-06 18:42:18 +01:00
|
|
|
struct wsi_device *wsi_device = device->wsi_device;
|
2018-06-16 18:44:11 +01:00
|
|
|
struct wsi_interface *iface = wsi_device->wsi[surface->platform];
|
|
|
|
|
|
|
|
assert(pSurfaceCapabilities->sType ==
|
|
|
|
VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT);
|
|
|
|
|
|
|
|
struct wsi_surface_supported_counters counters = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_WSI_SURFACE_SUPPORTED_COUNTERS_MESA,
|
|
|
|
.pNext = pSurfaceCapabilities->pNext,
|
|
|
|
.supported_surface_counters = 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
VkSurfaceCapabilities2KHR caps2 = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR,
|
|
|
|
.pNext = &counters,
|
|
|
|
};
|
|
|
|
|
2018-11-25 11:23:26 +00:00
|
|
|
VkResult result = iface->get_capabilities2(surface, wsi_device, NULL, &caps2);
|
2018-06-16 18:44:11 +01:00
|
|
|
|
|
|
|
if (result == VK_SUCCESS) {
|
|
|
|
VkSurfaceCapabilities2EXT *ext_caps = pSurfaceCapabilities;
|
|
|
|
VkSurfaceCapabilitiesKHR khr_caps = caps2.surfaceCapabilities;
|
|
|
|
|
|
|
|
ext_caps->minImageCount = khr_caps.minImageCount;
|
|
|
|
ext_caps->maxImageCount = khr_caps.maxImageCount;
|
|
|
|
ext_caps->currentExtent = khr_caps.currentExtent;
|
|
|
|
ext_caps->minImageExtent = khr_caps.minImageExtent;
|
|
|
|
ext_caps->maxImageExtent = khr_caps.maxImageExtent;
|
|
|
|
ext_caps->maxImageArrayLayers = khr_caps.maxImageArrayLayers;
|
|
|
|
ext_caps->supportedTransforms = khr_caps.supportedTransforms;
|
|
|
|
ext_caps->currentTransform = khr_caps.currentTransform;
|
|
|
|
ext_caps->supportedCompositeAlpha = khr_caps.supportedCompositeAlpha;
|
|
|
|
ext_caps->supportedUsageFlags = khr_caps.supportedUsageFlags;
|
|
|
|
ext_caps->supportedSurfaceCounters = counters.supported_surface_counters;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL
|
|
|
|
wsi_GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice,
|
2021-10-06 18:42:18 +01:00
|
|
|
VkSurfaceKHR _surface,
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
uint32_t *pSurfaceFormatCount,
|
|
|
|
VkSurfaceFormatKHR *pSurfaceFormats)
|
|
|
|
{
|
|
|
|
VK_FROM_HANDLE(vk_physical_device, device, physicalDevice);
|
2021-10-06 18:42:18 +01:00
|
|
|
ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
|
|
|
|
struct wsi_device *wsi_device = device->wsi_device;
|
2017-11-16 20:26:26 +00:00
|
|
|
struct wsi_interface *iface = wsi_device->wsi[surface->platform];
|
|
|
|
|
2021-10-06 18:42:18 +01:00
|
|
|
return iface->get_formats(surface, wsi_device,
|
|
|
|
pSurfaceFormatCount, pSurfaceFormats);
|
2017-11-16 20:26:26 +00:00
|
|
|
}
|
|
|
|
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL
|
|
|
|
wsi_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
|
|
|
|
const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,
|
|
|
|
uint32_t *pSurfaceFormatCount,
|
|
|
|
VkSurfaceFormat2KHR *pSurfaceFormats)
|
|
|
|
{
|
|
|
|
VK_FROM_HANDLE(vk_physical_device, device, physicalDevice);
|
2021-10-06 18:42:18 +01:00
|
|
|
ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pSurfaceInfo->surface);
|
|
|
|
struct wsi_device *wsi_device = device->wsi_device;
|
2017-11-16 20:26:26 +00:00
|
|
|
struct wsi_interface *iface = wsi_device->wsi[surface->platform];
|
|
|
|
|
2021-10-06 18:42:18 +01:00
|
|
|
return iface->get_formats2(surface, wsi_device, pSurfaceInfo->pNext,
|
|
|
|
pSurfaceFormatCount, pSurfaceFormats);
|
2017-11-16 20:26:26 +00:00
|
|
|
}
|
|
|
|
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL
|
|
|
|
wsi_GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,
|
2021-10-06 18:42:18 +01:00
|
|
|
VkSurfaceKHR _surface,
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
uint32_t *pPresentModeCount,
|
|
|
|
VkPresentModeKHR *pPresentModes)
|
|
|
|
{
|
|
|
|
VK_FROM_HANDLE(vk_physical_device, device, physicalDevice);
|
2018-10-15 03:56:34 +01:00
|
|
|
ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
|
2021-10-06 18:42:18 +01:00
|
|
|
struct wsi_device *wsi_device = device->wsi_device;
|
2018-10-15 03:56:34 +01:00
|
|
|
struct wsi_interface *iface = wsi_device->wsi[surface->platform];
|
|
|
|
|
2021-10-06 18:42:18 +01:00
|
|
|
return iface->get_present_modes(surface, pPresentModeCount,
|
|
|
|
pPresentModes);
|
2018-10-15 03:56:34 +01:00
|
|
|
}
|
|
|
|
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL
|
|
|
|
wsi_GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,
|
2021-10-06 18:42:18 +01:00
|
|
|
VkSurfaceKHR _surface,
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
uint32_t *pRectCount,
|
|
|
|
VkRect2D *pRects)
|
|
|
|
{
|
|
|
|
VK_FROM_HANDLE(vk_physical_device, device, physicalDevice);
|
2021-10-06 18:42:18 +01:00
|
|
|
ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
|
|
|
|
struct wsi_device *wsi_device = device->wsi_device;
|
|
|
|
struct wsi_interface *iface = wsi_device->wsi[surface->platform];
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
|
2021-10-06 18:42:18 +01:00
|
|
|
return iface->get_present_rectangles(surface, wsi_device,
|
|
|
|
pRectCount, pRects);
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
}
|
|
|
|
|
2021-10-06 18:42:18 +01:00
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL
|
|
|
|
wsi_CreateSwapchainKHR(VkDevice _device,
|
|
|
|
const VkSwapchainCreateInfoKHR *pCreateInfo,
|
|
|
|
const VkAllocationCallbacks *pAllocator,
|
|
|
|
VkSwapchainKHR *pSwapchain)
|
2017-11-16 02:02:04 +00:00
|
|
|
{
|
2021-10-06 18:42:18 +01:00
|
|
|
VK_FROM_HANDLE(vk_device, device, _device);
|
2017-11-16 02:02:04 +00:00
|
|
|
ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pCreateInfo->surface);
|
2021-10-06 18:42:18 +01:00
|
|
|
struct wsi_device *wsi_device = device->physical->wsi_device;
|
|
|
|
struct wsi_interface *iface = wsi_device->wsi[surface->platform];
|
|
|
|
const VkAllocationCallbacks *alloc;
|
2017-11-16 02:02:04 +00:00
|
|
|
struct wsi_swapchain *swapchain;
|
|
|
|
|
2021-10-06 18:42:18 +01:00
|
|
|
if (pAllocator)
|
|
|
|
alloc = pAllocator;
|
|
|
|
else
|
|
|
|
alloc = &device->alloc;
|
|
|
|
|
|
|
|
VkResult result = iface->create_swapchain(surface, _device, wsi_device,
|
|
|
|
pCreateInfo, alloc,
|
2017-11-16 02:02:04 +00:00
|
|
|
&swapchain);
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
return result;
|
|
|
|
|
2021-10-06 18:42:18 +01:00
|
|
|
swapchain->fences = vk_zalloc(alloc,
|
2019-05-20 01:51:51 +01:00
|
|
|
sizeof (*swapchain->fences) * swapchain->image_count,
|
|
|
|
sizeof (*swapchain->fences),
|
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
|
|
|
if (!swapchain->fences) {
|
2021-10-06 18:42:18 +01:00
|
|
|
swapchain->destroy(swapchain, alloc);
|
2019-05-20 01:51:51 +01:00
|
|
|
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
|
|
|
}
|
|
|
|
|
2022-02-03 09:57:16 +00:00
|
|
|
if (swapchain->buffer_blit_queue != VK_NULL_HANDLE) {
|
|
|
|
swapchain->buffer_blit_semaphores = vk_zalloc(alloc,
|
|
|
|
sizeof (*swapchain->buffer_blit_semaphores) * swapchain->image_count,
|
|
|
|
sizeof (*swapchain->buffer_blit_semaphores),
|
2021-12-08 13:05:15 +00:00
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
2022-02-03 09:57:16 +00:00
|
|
|
if (!swapchain->buffer_blit_semaphores) {
|
2021-12-08 13:05:15 +00:00
|
|
|
swapchain->destroy(swapchain, alloc);
|
|
|
|
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-16 02:02:04 +00:00
|
|
|
*pSwapchain = wsi_swapchain_to_handle(swapchain);
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
VKAPI_ATTR void VKAPI_CALL
|
|
|
|
wsi_DestroySwapchainKHR(VkDevice _device,
|
2021-10-06 18:42:18 +01:00
|
|
|
VkSwapchainKHR _swapchain,
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
const VkAllocationCallbacks *pAllocator)
|
|
|
|
{
|
|
|
|
VK_FROM_HANDLE(vk_device, device, _device);
|
2021-10-06 18:42:18 +01:00
|
|
|
VK_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain);
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
const VkAllocationCallbacks *alloc;
|
|
|
|
|
2021-10-06 18:42:18 +01:00
|
|
|
if (!swapchain)
|
|
|
|
return;
|
|
|
|
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
if (pAllocator)
|
|
|
|
alloc = pAllocator;
|
|
|
|
else
|
|
|
|
alloc = &device->alloc;
|
|
|
|
|
2021-10-06 18:42:18 +01:00
|
|
|
swapchain->destroy(swapchain, alloc);
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
}
|
|
|
|
|
2017-11-16 17:56:37 +00:00
|
|
|
VkResult
|
|
|
|
wsi_common_get_images(VkSwapchainKHR _swapchain,
|
|
|
|
uint32_t *pSwapchainImageCount,
|
|
|
|
VkImage *pSwapchainImages)
|
|
|
|
{
|
2020-04-21 23:00:39 +01:00
|
|
|
VK_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain);
|
2020-08-07 04:57:10 +01:00
|
|
|
VK_OUTARRAY_MAKE_TYPED(VkImage, images, pSwapchainImages, pSwapchainImageCount);
|
2017-11-16 17:56:37 +00:00
|
|
|
|
|
|
|
for (uint32_t i = 0; i < swapchain->image_count; i++) {
|
2020-08-07 04:57:10 +01:00
|
|
|
vk_outarray_append_typed(VkImage, &images, image) {
|
2017-11-16 17:56:37 +00:00
|
|
|
*image = swapchain->get_wsi_image(swapchain, i)->image;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return vk_outarray_status(&images);
|
|
|
|
}
|
|
|
|
|
2022-01-13 20:44:37 +00:00
|
|
|
VkImage
|
|
|
|
wsi_common_get_image(VkSwapchainKHR _swapchain, uint32_t index)
|
|
|
|
{
|
|
|
|
VK_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain);
|
|
|
|
assert(index < swapchain->image_count);
|
|
|
|
return swapchain->get_wsi_image(swapchain, index)->image;
|
|
|
|
}
|
|
|
|
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL
|
|
|
|
wsi_GetSwapchainImagesKHR(VkDevice device,
|
|
|
|
VkSwapchainKHR swapchain,
|
|
|
|
uint32_t *pSwapchainImageCount,
|
|
|
|
VkImage *pSwapchainImages)
|
|
|
|
{
|
|
|
|
return wsi_common_get_images(swapchain,
|
|
|
|
pSwapchainImageCount,
|
|
|
|
pSwapchainImages);
|
|
|
|
}
|
|
|
|
|
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL
|
|
|
|
wsi_AcquireNextImageKHR(VkDevice _device,
|
|
|
|
VkSwapchainKHR swapchain,
|
|
|
|
uint64_t timeout,
|
|
|
|
VkSemaphore semaphore,
|
|
|
|
VkFence fence,
|
|
|
|
uint32_t *pImageIndex)
|
|
|
|
{
|
|
|
|
VK_FROM_HANDLE(vk_device, device, _device);
|
|
|
|
|
|
|
|
const VkAcquireNextImageInfoKHR acquire_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR,
|
|
|
|
.swapchain = swapchain,
|
|
|
|
.timeout = timeout,
|
|
|
|
.semaphore = semaphore,
|
|
|
|
.fence = fence,
|
|
|
|
.deviceMask = 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
return device->dispatch_table.AcquireNextImage2KHR(_device, &acquire_info,
|
|
|
|
pImageIndex);
|
|
|
|
}
|
|
|
|
|
2017-11-16 18:44:41 +00:00
|
|
|
VkResult
|
2018-09-20 11:30:03 +01:00
|
|
|
wsi_common_acquire_next_image2(const struct wsi_device *wsi,
|
2021-12-15 09:52:44 +00:00
|
|
|
VkDevice _device,
|
2018-09-20 11:30:03 +01:00
|
|
|
const VkAcquireNextImageInfoKHR *pAcquireInfo,
|
|
|
|
uint32_t *pImageIndex)
|
2017-11-16 18:44:41 +00:00
|
|
|
{
|
2020-04-21 23:00:39 +01:00
|
|
|
VK_FROM_HANDLE(wsi_swapchain, swapchain, pAcquireInfo->swapchain);
|
2021-12-15 09:52:44 +00:00
|
|
|
VK_FROM_HANDLE(vk_device, device, _device);
|
2017-11-16 18:44:41 +00:00
|
|
|
|
2019-12-04 18:47:31 +00:00
|
|
|
VkResult result = swapchain->acquire_next_image(swapchain, pAcquireInfo,
|
|
|
|
pImageIndex);
|
2020-06-27 14:50:47 +01:00
|
|
|
if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)
|
2019-12-04 18:47:31 +00:00
|
|
|
return result;
|
|
|
|
|
2020-03-24 16:59:07 +00:00
|
|
|
if (wsi->set_memory_ownership) {
|
|
|
|
VkDeviceMemory mem = swapchain->get_wsi_image(swapchain, *pImageIndex)->memory;
|
|
|
|
wsi->set_memory_ownership(swapchain->device, mem, true);
|
|
|
|
}
|
|
|
|
|
2019-12-04 18:47:31 +00:00
|
|
|
if (pAcquireInfo->semaphore != VK_NULL_HANDLE &&
|
2021-12-15 09:52:44 +00:00
|
|
|
wsi->signal_semaphore_with_memory) {
|
|
|
|
VK_FROM_HANDLE(vk_semaphore, semaphore, pAcquireInfo->semaphore);
|
2019-12-04 18:47:31 +00:00
|
|
|
struct wsi_image *image =
|
|
|
|
swapchain->get_wsi_image(swapchain, *pImageIndex);
|
2021-12-15 09:52:44 +00:00
|
|
|
|
|
|
|
vk_semaphore_reset_temporary(device, semaphore);
|
|
|
|
VkResult lresult =
|
|
|
|
device->create_sync_for_memory(device, image->memory,
|
|
|
|
false /* signal_memory */,
|
|
|
|
&semaphore->temporary);
|
|
|
|
if (lresult != VK_SUCCESS)
|
|
|
|
return lresult;
|
2019-12-04 18:47:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (pAcquireInfo->fence != VK_NULL_HANDLE &&
|
2021-12-15 09:52:44 +00:00
|
|
|
wsi->signal_fence_with_memory) {
|
|
|
|
VK_FROM_HANDLE(vk_fence, fence, pAcquireInfo->fence);
|
2019-12-04 18:47:31 +00:00
|
|
|
struct wsi_image *image =
|
|
|
|
swapchain->get_wsi_image(swapchain, *pImageIndex);
|
2021-12-15 09:52:44 +00:00
|
|
|
|
|
|
|
vk_fence_reset_temporary(device, fence);
|
|
|
|
VkResult lresult =
|
|
|
|
device->create_sync_for_memory(device, image->memory,
|
|
|
|
false /* signal_memory */,
|
|
|
|
&fence->temporary);
|
|
|
|
if (lresult != VK_SUCCESS)
|
|
|
|
return lresult;
|
2019-12-04 18:47:31 +00:00
|
|
|
}
|
|
|
|
|
2020-06-27 14:50:47 +01:00
|
|
|
return result;
|
2017-11-16 18:44:41 +00:00
|
|
|
}
|
|
|
|
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL
|
|
|
|
wsi_AcquireNextImage2KHR(VkDevice _device,
|
|
|
|
const VkAcquireNextImageInfoKHR *pAcquireInfo,
|
|
|
|
uint32_t *pImageIndex)
|
|
|
|
{
|
|
|
|
VK_FROM_HANDLE(vk_device, device, _device);
|
|
|
|
|
|
|
|
return wsi_common_acquire_next_image2(device->physical->wsi_device,
|
|
|
|
_device, pAcquireInfo, pImageIndex);
|
|
|
|
}
|
|
|
|
|
2017-11-16 01:52:39 +00:00
|
|
|
VkResult
|
|
|
|
wsi_common_queue_present(const struct wsi_device *wsi,
|
|
|
|
VkDevice device,
|
|
|
|
VkQueue queue,
|
|
|
|
int queue_family_index,
|
|
|
|
const VkPresentInfoKHR *pPresentInfo)
|
|
|
|
{
|
2017-11-16 16:59:21 +00:00
|
|
|
VkResult final_result = VK_SUCCESS;
|
2017-11-16 01:52:39 +00:00
|
|
|
|
|
|
|
const VkPresentRegionsKHR *regions =
|
|
|
|
vk_find_struct_const(pPresentInfo->pNext, PRESENT_REGIONS_KHR);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < pPresentInfo->swapchainCount; i++) {
|
2020-04-21 23:00:39 +01:00
|
|
|
VK_FROM_HANDLE(wsi_swapchain, swapchain, pPresentInfo->pSwapchains[i]);
|
2019-05-20 01:51:51 +01:00
|
|
|
uint32_t image_index = pPresentInfo->pImageIndices[i];
|
2017-11-16 16:59:21 +00:00
|
|
|
VkResult result;
|
2017-11-16 01:52:39 +00:00
|
|
|
|
2019-05-20 01:51:51 +01:00
|
|
|
if (swapchain->fences[image_index] == VK_NULL_HANDLE) {
|
2017-11-16 01:52:39 +00:00
|
|
|
const VkFenceCreateInfo fence_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
|
|
|
|
.pNext = NULL,
|
|
|
|
.flags = 0,
|
|
|
|
};
|
2017-11-16 16:59:21 +00:00
|
|
|
result = wsi->CreateFence(device, &fence_info,
|
|
|
|
&swapchain->alloc,
|
2019-05-20 01:51:51 +01:00
|
|
|
&swapchain->fences[image_index]);
|
2017-11-16 16:59:21 +00:00
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
goto fail_present;
|
2021-12-08 13:05:15 +00:00
|
|
|
|
2022-02-03 09:57:16 +00:00
|
|
|
if (swapchain->use_buffer_blit && swapchain->buffer_blit_queue != VK_NULL_HANDLE) {
|
2021-12-08 13:05:15 +00:00
|
|
|
const VkSemaphoreCreateInfo sem_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
|
|
|
|
.pNext = NULL,
|
|
|
|
.flags = 0,
|
|
|
|
};
|
|
|
|
result = wsi->CreateSemaphore(device, &sem_info,
|
|
|
|
&swapchain->alloc,
|
2022-02-03 09:57:16 +00:00
|
|
|
&swapchain->buffer_blit_semaphores[image_index]);
|
2021-12-08 13:05:15 +00:00
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
goto fail_present;
|
|
|
|
}
|
2017-11-16 01:52:39 +00:00
|
|
|
} else {
|
2019-12-12 15:51:26 +00:00
|
|
|
result =
|
|
|
|
wsi->WaitForFences(device, 1, &swapchain->fences[image_index],
|
|
|
|
true, ~0ull);
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
goto fail_present;
|
2019-05-20 01:51:51 +01:00
|
|
|
|
2019-12-12 15:51:26 +00:00
|
|
|
result =
|
|
|
|
wsi->ResetFences(device, 1, &swapchain->fences[image_index]);
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
goto fail_present;
|
2017-11-16 01:52:39 +00:00
|
|
|
}
|
|
|
|
|
2019-11-21 11:47:10 +00:00
|
|
|
struct wsi_image *image =
|
|
|
|
swapchain->get_wsi_image(swapchain, image_index);
|
|
|
|
|
|
|
|
struct wsi_memory_signal_submit_info mem_signal = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_WSI_MEMORY_SIGNAL_SUBMIT_INFO_MESA,
|
|
|
|
.pNext = NULL,
|
|
|
|
.memory = image->memory,
|
|
|
|
};
|
|
|
|
|
2017-11-16 01:52:39 +00:00
|
|
|
VkSubmitInfo submit_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
2019-11-21 11:47:10 +00:00
|
|
|
.pNext = &mem_signal,
|
2017-11-16 01:52:39 +00:00
|
|
|
};
|
2017-11-16 17:30:16 +00:00
|
|
|
|
2017-11-16 17:18:48 +00:00
|
|
|
VkPipelineStageFlags *stage_flags = NULL;
|
2017-11-16 17:07:58 +00:00
|
|
|
if (i == 0) {
|
|
|
|
/* We only need/want to wait on semaphores once. After that, we're
|
|
|
|
* guaranteed ordering since it all happens on the same queue.
|
|
|
|
*/
|
2018-11-20 17:35:27 +00:00
|
|
|
submit_info.waitSemaphoreCount = pPresentInfo->waitSemaphoreCount;
|
|
|
|
submit_info.pWaitSemaphores = pPresentInfo->pWaitSemaphores;
|
2017-11-16 17:18:48 +00:00
|
|
|
|
|
|
|
/* Set up the pWaitDstStageMasks */
|
|
|
|
stage_flags = vk_alloc(&swapchain->alloc,
|
|
|
|
sizeof(VkPipelineStageFlags) *
|
|
|
|
pPresentInfo->waitSemaphoreCount,
|
|
|
|
8,
|
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
|
|
|
if (!stage_flags) {
|
|
|
|
result = VK_ERROR_OUT_OF_HOST_MEMORY;
|
|
|
|
goto fail_present;
|
|
|
|
}
|
|
|
|
for (uint32_t s = 0; s < pPresentInfo->waitSemaphoreCount; s++)
|
|
|
|
stage_flags[s] = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
|
|
|
|
|
|
|
|
submit_info.pWaitDstStageMask = stage_flags;
|
2017-11-16 17:07:58 +00:00
|
|
|
}
|
2017-11-16 17:30:16 +00:00
|
|
|
|
2021-12-08 13:05:15 +00:00
|
|
|
VkFence fence = swapchain->fences[image_index];
|
2022-02-03 09:57:16 +00:00
|
|
|
if (swapchain->use_buffer_blit) {
|
|
|
|
if (swapchain->buffer_blit_queue == VK_NULL_HANDLE) {
|
|
|
|
/* If we are using default buffer blits, we need to perform the blit now. The
|
2021-12-08 13:05:15 +00:00
|
|
|
* command buffer is attached to the image.
|
|
|
|
*/
|
|
|
|
submit_info.commandBufferCount = 1;
|
|
|
|
submit_info.pCommandBuffers =
|
2022-02-03 09:57:16 +00:00
|
|
|
&image->buffer.blit_cmd_buffers[queue_family_index];
|
|
|
|
mem_signal.memory = image->buffer.memory;
|
2021-12-08 13:05:15 +00:00
|
|
|
} else {
|
|
|
|
/* If we are using a blit using the driver's private queue, then do an empty
|
|
|
|
* submit signalling a semaphore, and then submit the blit.
|
|
|
|
*/
|
|
|
|
fence = VK_NULL_HANDLE;
|
|
|
|
submit_info.signalSemaphoreCount = 1;
|
2022-02-03 09:57:16 +00:00
|
|
|
submit_info.pSignalSemaphores = &swapchain->buffer_blit_semaphores[image_index];
|
2021-12-08 13:05:15 +00:00
|
|
|
}
|
2017-11-16 17:30:16 +00:00
|
|
|
}
|
|
|
|
|
2021-12-08 13:05:15 +00:00
|
|
|
result = wsi->QueueSubmit(queue, 1, &submit_info, fence);
|
2017-11-16 17:18:48 +00:00
|
|
|
vk_free(&swapchain->alloc, stage_flags);
|
2017-11-16 16:59:21 +00:00
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
goto fail_present;
|
2017-11-16 01:52:39 +00:00
|
|
|
|
2022-02-03 09:57:16 +00:00
|
|
|
if (swapchain->use_buffer_blit && swapchain->buffer_blit_queue != VK_NULL_HANDLE) {
|
2021-12-08 13:05:15 +00:00
|
|
|
submit_info.commandBufferCount = 1;
|
|
|
|
|
2022-02-03 09:57:16 +00:00
|
|
|
if (swapchain->buffer_blit_queue != VK_NULL_HANDLE) {
|
|
|
|
submit_info.pCommandBuffers = &image->buffer.blit_cmd_buffers[0];
|
2021-12-08 13:05:15 +00:00
|
|
|
submit_info.waitSemaphoreCount = 1;
|
|
|
|
submit_info.pWaitSemaphores = submit_info.pSignalSemaphores;
|
|
|
|
submit_info.signalSemaphoreCount = 0;
|
|
|
|
submit_info.pSignalSemaphores = NULL;
|
|
|
|
/* Submit the copy to the private transfer queue */
|
2022-02-03 09:57:16 +00:00
|
|
|
result = wsi->QueueSubmit(swapchain->buffer_blit_queue,
|
2021-12-08 13:05:15 +00:00
|
|
|
1,
|
|
|
|
&submit_info,
|
|
|
|
swapchain->fences[image_index]);
|
|
|
|
}
|
2022-02-03 09:57:16 +00:00
|
|
|
mem_signal.memory = image->buffer.memory;
|
2021-12-08 13:05:15 +00:00
|
|
|
}
|
|
|
|
|
2021-08-23 04:00:56 +01:00
|
|
|
if (wsi->sw)
|
|
|
|
wsi->WaitForFences(device, 1, &swapchain->fences[image_index],
|
|
|
|
true, ~0ull);
|
|
|
|
|
2017-11-16 01:52:39 +00:00
|
|
|
const VkPresentRegionKHR *region = NULL;
|
|
|
|
if (regions && regions->pRegions)
|
|
|
|
region = ®ions->pRegions[i];
|
|
|
|
|
2019-05-20 01:51:51 +01:00
|
|
|
result = swapchain->queue_present(swapchain, image_index, region);
|
2020-06-27 14:50:47 +01:00
|
|
|
if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)
|
2017-11-16 16:59:21 +00:00
|
|
|
goto fail_present;
|
2017-11-16 01:52:39 +00:00
|
|
|
|
2020-03-24 16:59:07 +00:00
|
|
|
if (wsi->set_memory_ownership) {
|
|
|
|
VkDeviceMemory mem = swapchain->get_wsi_image(swapchain, image_index)->memory;
|
|
|
|
wsi->set_memory_ownership(swapchain->device, mem, false);
|
|
|
|
}
|
|
|
|
|
2017-11-16 16:59:21 +00:00
|
|
|
fail_present:
|
|
|
|
if (pPresentInfo->pResults != NULL)
|
|
|
|
pPresentInfo->pResults[i] = result;
|
|
|
|
|
|
|
|
/* Let the final result be our first unsuccessful result */
|
|
|
|
if (final_result == VK_SUCCESS)
|
|
|
|
final_result = result;
|
2017-11-16 01:52:39 +00:00
|
|
|
}
|
2017-11-16 16:59:21 +00:00
|
|
|
|
|
|
|
return final_result;
|
2017-11-16 01:52:39 +00:00
|
|
|
}
|
2018-10-28 13:37:26 +00:00
|
|
|
|
vulkan/wsi: Add common wrappers for most entrypoints
For a long time, our Vulkan WSI code has acted as something of a layer.
The WSI code calls into various Vulkan entrypoints inside the driver to
create images, allocate memory, etc. It then implements the API-facing
interface almost entirely. The only thing the driver has to provide is
little wrappers that wrap around the WSI calls to expose them through
the API.
However, now that we have a common dispatch framework, we can implement
entrypoints directly in the WSI code. As long as the driver uses
vk_instance, vk_physical_device, and vk_device, we can provide common
wrappers for the vast majority of entrypoints. The only exceptions are
vkAcquireNextImage, vkQueuePresent, vkRegisterDeviceEventEXT, and
vkRegisterDisplayEventEXT because those may have to manually poke at
synchronization primitives. We provide wrappers for vkAcquireNextImage
and vkQueuePresent because some drivers can use the default versions.
For now, we're intentionally avoiding any link-time dependencies between
WSI and the common code. We only use VK_FROM_HANDLE and associated
inline helpers and vk_physical_device has a pointer to a wsi_device.
Eventually, we may tie the two together closer, but this lets us get 95%
of the way there without reworking the universe.
Acked-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13234>
2021-10-06 17:09:12 +01:00
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL
|
|
|
|
wsi_QueuePresentKHR(VkQueue _queue, const VkPresentInfoKHR *pPresentInfo)
|
|
|
|
{
|
|
|
|
VK_FROM_HANDLE(vk_queue, queue, _queue);
|
|
|
|
|
|
|
|
return wsi_common_queue_present(queue->base.device->physical->wsi_device,
|
|
|
|
vk_device_to_handle(queue->base.device),
|
|
|
|
_queue,
|
|
|
|
queue->queue_family_index,
|
|
|
|
pPresentInfo);
|
|
|
|
}
|
|
|
|
|
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL
|
|
|
|
wsi_GetDeviceGroupPresentCapabilitiesKHR(VkDevice device,
|
|
|
|
VkDeviceGroupPresentCapabilitiesKHR *pCapabilities)
|
|
|
|
{
|
|
|
|
memset(pCapabilities->presentMask, 0,
|
|
|
|
sizeof(pCapabilities->presentMask));
|
|
|
|
pCapabilities->presentMask[0] = 0x1;
|
|
|
|
pCapabilities->modes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL
|
|
|
|
wsi_GetDeviceGroupSurfacePresentModesKHR(VkDevice device,
|
|
|
|
VkSurfaceKHR surface,
|
|
|
|
VkDeviceGroupPresentModeFlagsKHR *pModes)
|
|
|
|
{
|
|
|
|
*pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
}
|
2021-07-23 05:58:14 +01:00
|
|
|
|
|
|
|
VkResult
|
|
|
|
wsi_common_create_swapchain_image(const struct wsi_device *wsi,
|
|
|
|
const VkImageCreateInfo *pCreateInfo,
|
|
|
|
VkSwapchainKHR _swapchain,
|
|
|
|
VkImage *pImage)
|
|
|
|
{
|
|
|
|
VK_FROM_HANDLE(wsi_swapchain, chain, _swapchain);
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
const VkImageCreateInfo *swcInfo = &chain->image_info.create;
|
|
|
|
assert(pCreateInfo->flags == 0);
|
|
|
|
assert(pCreateInfo->imageType == swcInfo->imageType);
|
|
|
|
assert(pCreateInfo->format == swcInfo->format);
|
|
|
|
assert(pCreateInfo->extent.width == swcInfo->extent.width);
|
|
|
|
assert(pCreateInfo->extent.height == swcInfo->extent.height);
|
|
|
|
assert(pCreateInfo->extent.depth == swcInfo->extent.depth);
|
|
|
|
assert(pCreateInfo->mipLevels == swcInfo->mipLevels);
|
|
|
|
assert(pCreateInfo->arrayLayers == swcInfo->arrayLayers);
|
|
|
|
assert(pCreateInfo->samples == swcInfo->samples);
|
|
|
|
assert(pCreateInfo->tiling == VK_IMAGE_TILING_OPTIMAL);
|
|
|
|
assert(!(pCreateInfo->usage & ~swcInfo->usage));
|
|
|
|
|
|
|
|
vk_foreach_struct(ext, pCreateInfo->pNext) {
|
|
|
|
switch (ext->sType) {
|
|
|
|
case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO: {
|
|
|
|
const VkImageFormatListCreateInfo *iflci =
|
|
|
|
(const VkImageFormatListCreateInfo *)ext;
|
|
|
|
const VkImageFormatListCreateInfo *swc_iflci =
|
|
|
|
&chain->image_info.format_list;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < iflci->viewFormatCount; i++) {
|
|
|
|
bool found = false;
|
|
|
|
for (uint32_t j = 0; j < swc_iflci->viewFormatCount; j++) {
|
|
|
|
if (iflci->pViewFormats[i] == swc_iflci->pViewFormats[j]) {
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert(found);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
assert(!"Unsupported image create extension");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return wsi->CreateImage(chain->device, &chain->image_info.create,
|
|
|
|
&chain->alloc, pImage);
|
|
|
|
}
|
|
|
|
|
|
|
|
VkResult
|
|
|
|
wsi_common_bind_swapchain_image(const struct wsi_device *wsi,
|
|
|
|
VkImage vk_image,
|
|
|
|
VkSwapchainKHR _swapchain,
|
|
|
|
uint32_t image_idx)
|
|
|
|
{
|
|
|
|
VK_FROM_HANDLE(wsi_swapchain, chain, _swapchain);
|
|
|
|
struct wsi_image *image = chain->get_wsi_image(chain, image_idx);
|
|
|
|
|
|
|
|
return wsi->BindImageMemory(chain->device, vk_image, image->memory, 0);
|
|
|
|
}
|
2022-02-03 09:57:16 +00:00
|
|
|
|
|
|
|
VkResult
|
|
|
|
wsi_create_buffer_image_mem(const struct wsi_swapchain *chain,
|
|
|
|
const struct wsi_image_info *info,
|
|
|
|
struct wsi_image *image,
|
|
|
|
VkExternalMemoryHandleTypeFlags handle_types,
|
|
|
|
bool implicit_sync)
|
|
|
|
{
|
|
|
|
const struct wsi_device *wsi = chain->wsi;
|
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
uint32_t linear_size = info->linear_stride * info->create.extent.height;
|
|
|
|
linear_size = ALIGN_POT(linear_size, info->size_align);
|
|
|
|
|
|
|
|
const VkExternalMemoryBufferCreateInfo buffer_external_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
|
|
|
|
.pNext = NULL,
|
|
|
|
.handleTypes = handle_types,
|
|
|
|
};
|
|
|
|
const VkBufferCreateInfo buffer_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
|
|
|
.pNext = &buffer_external_info,
|
|
|
|
.size = linear_size,
|
|
|
|
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
|
|
|
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
|
|
|
};
|
|
|
|
result = wsi->CreateBuffer(chain->device, &buffer_info,
|
|
|
|
&chain->alloc, &image->buffer.buffer);
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
return result;
|
|
|
|
|
|
|
|
VkMemoryRequirements reqs;
|
|
|
|
wsi->GetBufferMemoryRequirements(chain->device, image->buffer.buffer, &reqs);
|
|
|
|
assert(reqs.size <= linear_size);
|
|
|
|
|
|
|
|
const struct wsi_memory_allocate_info memory_wsi_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO_MESA,
|
|
|
|
.pNext = NULL,
|
|
|
|
.implicit_sync = implicit_sync,
|
|
|
|
};
|
|
|
|
const VkExportMemoryAllocateInfo memory_export_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
|
|
|
|
.pNext = &memory_wsi_info,
|
|
|
|
.handleTypes = handle_types,
|
|
|
|
};
|
|
|
|
const VkMemoryDedicatedAllocateInfo buf_mem_dedicated_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
|
|
|
|
.pNext = &memory_export_info,
|
|
|
|
.image = VK_NULL_HANDLE,
|
|
|
|
.buffer = image->buffer.buffer,
|
|
|
|
};
|
|
|
|
const VkMemoryAllocateInfo buf_mem_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
|
|
|
.pNext = &buf_mem_dedicated_info,
|
|
|
|
.allocationSize = linear_size,
|
|
|
|
.memoryTypeIndex =
|
|
|
|
info->select_buffer_memory_type(wsi, reqs.memoryTypeBits),
|
|
|
|
};
|
|
|
|
result = wsi->AllocateMemory(chain->device, &buf_mem_info,
|
|
|
|
&chain->alloc, &image->buffer.memory);
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
return result;
|
|
|
|
|
|
|
|
result = wsi->BindBufferMemory(chain->device, image->buffer.buffer,
|
|
|
|
image->buffer.memory, 0);
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
return result;
|
|
|
|
|
|
|
|
wsi->GetImageMemoryRequirements(chain->device, image->image, &reqs);
|
|
|
|
|
|
|
|
const VkMemoryDedicatedAllocateInfo memory_dedicated_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
|
|
|
|
.pNext = NULL,
|
|
|
|
.image = image->image,
|
|
|
|
.buffer = VK_NULL_HANDLE,
|
|
|
|
};
|
|
|
|
const VkMemoryAllocateInfo memory_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
|
|
|
.pNext = &memory_dedicated_info,
|
|
|
|
.allocationSize = reqs.size,
|
|
|
|
.memoryTypeIndex =
|
|
|
|
info->select_image_memory_type(wsi, reqs.memoryTypeBits),
|
|
|
|
};
|
|
|
|
|
|
|
|
result = wsi->AllocateMemory(chain->device, &memory_info,
|
|
|
|
&chain->alloc, &image->memory);
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
return result;
|
|
|
|
|
|
|
|
image->num_planes = 1;
|
|
|
|
image->sizes[0] = linear_size;
|
|
|
|
image->row_pitches[0] = info->linear_stride;
|
|
|
|
image->offsets[0] = 0;
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
VkResult
|
|
|
|
wsi_finish_create_buffer_image(const struct wsi_swapchain *chain,
|
|
|
|
const struct wsi_image_info *info,
|
|
|
|
struct wsi_image *image)
|
|
|
|
{
|
|
|
|
const struct wsi_device *wsi = chain->wsi;
|
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
int cmd_buffer_count =
|
|
|
|
chain->buffer_blit_queue != VK_NULL_HANDLE ? 1 : wsi->queue_family_count;
|
|
|
|
image->buffer.blit_cmd_buffers =
|
|
|
|
vk_zalloc(&chain->alloc,
|
|
|
|
sizeof(VkCommandBuffer) * cmd_buffer_count, 8,
|
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
|
|
|
if (!image->buffer.blit_cmd_buffers)
|
|
|
|
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < cmd_buffer_count; i++) {
|
|
|
|
const VkCommandBufferAllocateInfo cmd_buffer_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
|
|
|
.pNext = NULL,
|
|
|
|
.commandPool = chain->cmd_pools[i],
|
|
|
|
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
|
|
|
.commandBufferCount = 1,
|
|
|
|
};
|
|
|
|
result = wsi->AllocateCommandBuffers(chain->device, &cmd_buffer_info,
|
|
|
|
&image->buffer.blit_cmd_buffers[i]);
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
return result;
|
|
|
|
|
|
|
|
const VkCommandBufferBeginInfo begin_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
|
|
|
};
|
|
|
|
wsi->BeginCommandBuffer(image->buffer.blit_cmd_buffers[i], &begin_info);
|
2021-07-19 14:32:19 +01:00
|
|
|
|
|
|
|
VkImageMemoryBarrier img_mem_barrier = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
|
|
|
.pNext = NULL,
|
|
|
|
.srcAccessMask = 0,
|
|
|
|
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
|
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
|
|
|
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
.image = image->image,
|
|
|
|
.subresourceRange = {
|
|
|
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
|
|
.baseMipLevel = 0,
|
|
|
|
.levelCount = 1,
|
|
|
|
.baseArrayLayer = 0,
|
|
|
|
.layerCount = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
wsi->CmdPipelineBarrier(image->buffer.blit_cmd_buffers[i],
|
|
|
|
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
|
|
0,
|
|
|
|
0, NULL,
|
|
|
|
0, NULL,
|
|
|
|
1, &img_mem_barrier);
|
|
|
|
|
2022-02-03 09:57:16 +00:00
|
|
|
struct VkBufferImageCopy buffer_image_copy = {
|
|
|
|
.bufferOffset = 0,
|
|
|
|
.bufferRowLength = info->linear_stride /
|
|
|
|
vk_format_get_blocksize(info->create.format),
|
|
|
|
.bufferImageHeight = 0,
|
|
|
|
.imageSubresource = {
|
|
|
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
|
|
.mipLevel = 0,
|
|
|
|
.baseArrayLayer = 0,
|
|
|
|
.layerCount = 1,
|
|
|
|
},
|
|
|
|
.imageOffset = { .x = 0, .y = 0, .z = 0 },
|
|
|
|
.imageExtent = info->create.extent,
|
|
|
|
};
|
|
|
|
wsi->CmdCopyImageToBuffer(image->buffer.blit_cmd_buffers[i],
|
|
|
|
image->image,
|
2021-07-19 14:32:19 +01:00
|
|
|
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
2022-02-03 09:57:16 +00:00
|
|
|
image->buffer.buffer,
|
|
|
|
1, &buffer_image_copy);
|
|
|
|
|
2021-07-19 14:32:19 +01:00
|
|
|
img_mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
|
|
|
img_mem_barrier.dstAccessMask = 0;
|
|
|
|
img_mem_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
|
|
|
img_mem_barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
|
|
|
wsi->CmdPipelineBarrier(image->buffer.blit_cmd_buffers[i],
|
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
|
|
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
|
|
|
0,
|
|
|
|
0, NULL,
|
|
|
|
0, NULL,
|
|
|
|
1, &img_mem_barrier);
|
|
|
|
|
2022-02-03 09:57:16 +00:00
|
|
|
result = wsi->EndCommandBuffer(image->buffer.blit_cmd_buffers[i]);
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
VkResult
|
|
|
|
wsi_configure_buffer_image(UNUSED const struct wsi_swapchain *chain,
|
|
|
|
const VkSwapchainCreateInfoKHR *pCreateInfo,
|
|
|
|
struct wsi_image_info *info)
|
|
|
|
{
|
|
|
|
VkResult result = wsi_configure_image(chain, pCreateInfo,
|
|
|
|
0 /* handle_types */, info);
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
return result;
|
|
|
|
|
|
|
|
info->create.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
|
|
|
info->wsi.buffer_blit_src = true;
|
|
|
|
info->finish_create = wsi_finish_create_buffer_image;
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
}
|