窗口系统集成 (WSI)
本章讨论 Vulkan API 和将渲染结果显示给用户的各种形式之间的窗口系统集成 (WSI)。由于 Vulkan API 可以在不显示结果的情况下使用,因此 WSI 通过使用可选的 Vulkan 扩展来提供。本章概述了 WSI。有关每个 WSI 扩展的更多详细信息,请参阅附录,包括为了使用本章中描述的每个函数 必须 启用哪些扩展。
WSI 平台
平台是窗口系统、操作系统等的抽象。一些示例包括 MS Windows、Android 和 Wayland。对于每个平台,Vulkan API 可能以独特的方式集成。
Vulkan API 不定义任何类型的平台对象。定义了特定于平台的 WSI 扩展,每个扩展都包含用于使用 WSI 的特定于平台的函数。这些扩展的使用受到预处理器符号的保护,如 窗口系统特定头文件控制 附录中所定义。
为了编译应用程序以将 WSI 与给定的平台一起使用,它必须满足以下任一条件:
-
在包含
vulkan.h头文件之前#define相应的预处理器符号,或 -
包含
vulkan_core.h和任何原生平台头文件,然后是相应的特定于平台的头文件。
预处理器符号和特定于平台的头文件在 窗口系统扩展和头文件 表中定义。
每个特定于平台的扩展都是实例扩展。应用程序 必须 在使用 vkCreateInstance 启用实例扩展。
WSI Surface
原生平台 surface 或窗口对象由 surface 对象抽象,这些对象由 VkSurfaceKHR 句柄表示。
// Provided by VK_KHR_surface
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR)
VK_KHR_surface 扩展声明了 VkSurfaceKHR 对象,并提供了一个用于销毁 VkSurfaceKHR 对象的函数。单独的特定于平台的扩展各自提供了一个用于为各自平台创建 VkSurfaceKHR 对象的函数。从应用程序的角度来看,这只是一个不透明的句柄,就像其他 Vulkan 对象的句柄一样。
Android 平台
要为 Android 原生窗口创建 VkSurfaceKHR 对象,请调用
// Provided by VK_KHR_android_surface
VkResult vkCreateAndroidSurfaceKHR(
VkInstance instance,
const VkAndroidSurfaceCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
-
instance是与 surface 关联的实例。 -
pCreateInfo是指向VkAndroidSurfaceCreateInfoKHR结构的指针,该结构包含影响 surface 对象创建的参数。 -
pAllocator是当没有更具体的分配器可用时(请参阅 内存分配)用于为 surface 对象分配主机内存的分配器。 -
pSurface是指向 VkSurfaceKHR 句柄的指针,其中返回创建的 surface 对象。
在使用特定 ANativeWindow 句柄创建的 surface 的生命周期中,任何尝试为同一 ANativeWindow 创建另一个 surface 的尝试以及任何通过其他平台机制连接到同一 ANativeWindow 的尝试都将失败。
|
特别是,对于给定的窗口,一次只能存在一个 |
如果成功,vkCreateAndroidSurfaceKHR 会递增 ANativeWindow 的引用计数,而 vkDestroySurfaceKHR 会递减它。
在 Android 上,当交换链的 imageExtent 与 surface 的 currentExtent 不匹配时,可呈现图像将在演示期间缩放到 surface 的尺寸。 minImageExtent 是 (1,1),而 maxImageExtent 是消费者支持的最大图像大小。对于系统合成器,currentExtent 是窗口大小(即消费者的首选大小)。
VkAndroidSurfaceCreateInfoKHR 结构定义为
// Provided by VK_KHR_android_surface
typedef struct VkAndroidSurfaceCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkAndroidSurfaceCreateFlagsKHR flags;
struct ANativeWindow* window;
} VkAndroidSurfaceCreateInfoKHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
flags保留供将来使用。 -
window是指向要将表面与之关联的ANativeWindow的指针。
为了删除不必要的编译时依赖,Vulkan 头部中提供了 ANativeWindow 的不完整类型定义
// Provided by VK_KHR_android_surface
struct ANativeWindow;
实际的 ANativeWindow 类型在 Android NDK 头部中定义。
// Provided by VK_KHR_android_surface
typedef VkFlags VkAndroidSurfaceCreateFlagsKHR;
VkAndroidSurfaceCreateFlagsKHR 是用于设置掩码的位掩码类型,但目前保留供将来使用。
Wayland 平台
要为 Wayland 表面创建 VkSurfaceKHR 对象,请调用
// Provided by VK_KHR_wayland_surface
VkResult vkCreateWaylandSurfaceKHR(
VkInstance instance,
const VkWaylandSurfaceCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
-
instance是与 surface 关联的实例。 -
pCreateInfo是指向 VkWaylandSurfaceCreateInfoKHR 结构的指针,该结构包含影响表面对象创建的参数。 -
pAllocator是当没有更具体的分配器可用时(请参阅 内存分配)用于为 surface 对象分配主机内存的分配器。 -
pSurface是指向 VkSurfaceKHR 句柄的指针,其中返回创建的 surface 对象。
VkWaylandSurfaceCreateInfoKHR 结构定义如下
// Provided by VK_KHR_wayland_surface
typedef struct VkWaylandSurfaceCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkWaylandSurfaceCreateFlagsKHR flags;
struct wl_display* display;
struct wl_surface* surface;
} VkWaylandSurfaceCreateInfoKHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
flags保留供将来使用。 -
display和surface是指向 Waylandwl_display和wl_surface的指针,用于将表面与之关联。
在 Wayland 上,currentExtent 是特殊值 (0xFFFFFFFF, 0xFFFFFFFF),表示表面大小将由以该表面为目标的交换链的范围确定。应用程序将交换链的 imageExtent 设置为任何值,都将成为窗口的大小,在呈现第一张图像之后。minImageExtent 为 (1,1),maxImageExtent 是支持的最大表面大小。在通过 vkCreateWaylandSurfaceKHR 创建的表面上调用 vkGetPhysicalDeviceSurfacePresentModesKHR 必须 返回 VK_PRESENT_MODE_MAILBOX_KHR 作为有效的呈现模式之一。
当使用从引用 wl_surface 的 VkSurfaceKHR 创建的交换链或可呈现图像时,某些 Vulkan 函数 可能 通过指定的 wl_display 连接发送协议。因此,应用程序 必须 确保 wl_display 和 wl_surface 在从特定的 wl_display 和 wl_surface 创建的任何 VkSwapchainKHR 对象的生命周期内保持有效。此外,调用 vkQueuePresentKHR 将导致 Vulkan 向每个 wl_surface 的底层 wl_surface 发送 wl_surface.commit 请求。wl_surface.attach、wl_surface.damage 和 wl_surface.commit 请求 必须 由实现在调用 vkQueuePresentKHR 期间发出,并且 不得 在 vkQueuePresentKHR 之外由实现发出。这确保了客户端在调用 vkQueuePresentKHR 返回后发送的任何 Wayland 请求将在合成器接收到 wl_surface.commit 之后被接收。无论交换链创建的模式如何,每次成功调用 vkCreateWaylandSurfaceKHR 都 必须 创建一个新的 wl_event_queue,并且实现创建的每个 Wayland 对象 必须 分配给此事件队列。如果平台提供 Wayland 1.11 或更高版本,则 必须 通过使用 Wayland 代理对象包装器来实现这一点,以避免竞争条件。
如果应用程序希望将任何窗口更改与特定帧同步,则此类请求 必须 在调用 vkQueuePresentKHR 之前发送到 Wayland 显示服务器。
// Provided by VK_KHR_wayland_surface
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
VkWaylandSurfaceCreateFlagsKHR 是用于设置掩码的位掩码类型,但目前保留供将来使用。
Win32 平台
要为 Win32 窗口创建 VkSurfaceKHR 对象,请调用
// Provided by VK_KHR_win32_surface
VkResult vkCreateWin32SurfaceKHR(
VkInstance instance,
const VkWin32SurfaceCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
-
instance是与 surface 关联的实例。 -
pCreateInfo是指向VkWin32SurfaceCreateInfoKHR结构的指针,该结构包含影响表面对象创建的参数。 -
pAllocator是当没有更具体的分配器可用时(请参阅 内存分配)用于为 surface 对象分配主机内存的分配器。 -
pSurface是指向 VkSurfaceKHR 句柄的指针,其中返回创建的 surface 对象。
某些Vulkan函数在通过 VkSwapchainKHR 与 VkSurfaceKHR 交互时可能会调用 SendMessage 系统 API。在多线程环境中,从与 pCreateInfo->hwnd 关联的线程不同的线程调用 SendMessage 将会阻塞,直到应用程序处理完窗口消息。因此,应用程序应该在消息泵线程上调用这些 Vulkan 函数,或者确保其消息泵正在主动运行。否则可能导致死锁。
受此要求的函数包括:
VkWin32SurfaceCreateInfoKHR 结构的定义如下:
// Provided by VK_KHR_win32_surface
typedef struct VkWin32SurfaceCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkWin32SurfaceCreateFlagsKHR flags;
HINSTANCE hinstance;
HWND hwnd;
} VkWin32SurfaceCreateInfoKHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
flags保留供将来使用。 -
hinstance是与表面关联的窗口的 Win32HINSTANCE。 -
hwnd是与表面关联的窗口的 Win32HWND。
对于 Win32,minImageExtent、maxImageExtent 和 currentExtent 必须始终等于窗口大小。
Win32 表面的 currentExtent 的 width 和 height 必须都大于 0,或者都为 0。
|
由于上述限制,除非使用 VkSwapchainPresentScalingCreateInfoEXT 来指定表面和交换链尺寸之间差异的处理方式,否则在此平台上只能创建 在此平台上,窗口大小可能变为 (0, 0) (例如,当窗口最小化时),因此在大小更改之前无法创建交换链。 |
// Provided by VK_KHR_win32_surface
typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
VkWin32SurfaceCreateFlagsKHR 是用于设置掩码的位掩码类型,但目前保留供将来使用。
XCB 平台
要使用 XCB 客户端库为 X11 窗口创建 VkSurfaceKHR 对象,请调用
// Provided by VK_KHR_xcb_surface
VkResult vkCreateXcbSurfaceKHR(
VkInstance instance,
const VkXcbSurfaceCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
-
instance是与 surface 关联的实例。 -
pCreateInfo是指向VkXcbSurfaceCreateInfoKHR结构的指针,该结构包含影响表面对象创建的参数。 -
pAllocator是当没有更具体的分配器可用时(请参阅 内存分配)用于为 surface 对象分配主机内存的分配器。 -
pSurface是指向 VkSurfaceKHR 句柄的指针,其中返回创建的 surface 对象。
VkXcbSurfaceCreateInfoKHR 结构的定义如下:
// Provided by VK_KHR_xcb_surface
typedef struct VkXcbSurfaceCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkXcbSurfaceCreateFlagsKHR flags;
xcb_connection_t* connection;
xcb_window_t window;
} VkXcbSurfaceCreateInfoKHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
flags保留供将来使用。 -
connection是指向 X 服务器的xcb_connection_t的指针。 -
window是与表面关联的 X11 窗口的xcb_window_t。
对于 Xcb,minImageExtent、maxImageExtent 和 currentExtent 必须始终等于窗口大小。
Xcb 表面的 currentExtent 的 width 和 height 必须都大于 0,或者都为 0。
|
由于上述限制,除非使用 VkSwapchainPresentScalingCreateInfoEXT 来指定表面和交换链尺寸之间差异的处理方式,否则在此平台上只能创建 在此平台上,窗口大小可能变为 (0, 0) (例如,当窗口最小化时),因此在大小更改之前无法创建交换链。 |
某些 Vulkan 函数在使用从引用 xcb 窗口的 VkSurfaceKHR 创建的交换链或可呈现图像时,可能会通过指定的 xcb 连接发送协议。因此,应用程序必须确保 Vulkan 在任何操作此类交换链或其可呈现图像的函数,以及任何构建或排队操作此类可呈现图像的命令缓冲区的函数执行期间,都可以访问 xcb 连接。具体而言,使用基于 xcb 的交换链的 Vulkan 应用程序必须
-
避免在等待 Vulkan 操作完成时,使用引用同一 X 服务器实例的不同 xcb 连接上的交换链时,持有 xcb 连接的服务器抓取。否则可能导致死锁。
// Provided by VK_KHR_xcb_surface
typedef VkFlags VkXcbSurfaceCreateFlagsKHR;
VkXcbSurfaceCreateFlagsKHR 是用于设置掩码的位掩码类型,但目前保留供将来使用。
Xlib 平台
要使用 Xlib 客户端库为 X11 窗口创建 VkSurfaceKHR 对象,请调用
// Provided by VK_KHR_xlib_surface
VkResult vkCreateXlibSurfaceKHR(
VkInstance instance,
const VkXlibSurfaceCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
-
instance是与 surface 关联的实例。 -
pCreateInfo是指向VkXlibSurfaceCreateInfoKHR结构的指针,该结构包含影响表面对象创建的参数。 -
pAllocator是当没有更具体的分配器可用时(请参阅 内存分配)用于为 surface 对象分配主机内存的分配器。 -
pSurface是指向 VkSurfaceKHR 句柄的指针,其中返回创建的 surface 对象。
VkXlibSurfaceCreateInfoKHR 结构的定义如下:
// Provided by VK_KHR_xlib_surface
typedef struct VkXlibSurfaceCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkXlibSurfaceCreateFlagsKHR flags;
Display* dpy;
Window window;
} VkXlibSurfaceCreateInfoKHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
flags保留供将来使用。 -
dpy是指向 XlibDisplay连接到 X 服务器的指针。 -
window是与表面关联的 XlibWindow。
对于 Xlib,minImageExtent、maxImageExtent 和 currentExtent 必须始终等于窗口大小。
Xlib 表面的 currentExtent 的 width 和 height 都 必须 大于 0,或者都为 0。
|
由于上述限制,除非使用 VkSwapchainPresentScalingCreateInfoEXT 来指定表面和交换链尺寸之间差异的处理方式,否则在此平台上只能创建 在此平台上,窗口大小可能变为 (0, 0) (例如,当窗口最小化时),因此在大小更改之前无法创建交换链。 |
当使用由引用 Xlib 窗口的 VkSurfaceKHR 创建的交换链或可呈现图像时,某些 Vulkan 函数 可能 会通过指定的 Xlib Display 连接发送协议。因此,应用程序 必须 确保在任何操作此类交换链或其可呈现图像的函数,以及任何构建或排队操作此类可呈现图像的命令缓冲区的函数期间,Vulkan 可以使用显示连接。具体来说,使用基于 Xlib 的交换链的 Vulkan 应用程序 必须:
-
在使用从引用同一 X 服务器实例的不同显示连接派生的交换链等待 Vulkan 操作完成时,避免在显示连接上保持服务器抓取。否则 可能 会导致死锁。
某些实现可能需要线程来实现某些呈现模式,因此应用程序 必须 在调用任何其他 Xlib 函数之前调用 XInitThreads()。
// Provided by VK_KHR_xlib_surface
typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
VkXlibSurfaceCreateFlagsKHR 是一种用于设置掩码的位掩码类型,但目前保留供将来使用。
DirectFB 平台
要为 DirectFB 表面创建 VkSurfaceKHR 对象,请调用
// Provided by VK_EXT_directfb_surface
VkResult vkCreateDirectFBSurfaceEXT(
VkInstance instance,
const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
-
instance是与 surface 关联的实例。 -
pCreateInfo是指向一个VkDirectFBSurfaceCreateInfoEXT结构的指针,该结构包含影响表面对象创建的参数。 -
pAllocator是当没有更具体的分配器可用时(请参阅 内存分配)用于为 surface 对象分配主机内存的分配器。 -
pSurface是指向 VkSurfaceKHR 句柄的指针,其中返回创建的 surface 对象。
VkDirectFBSurfaceCreateInfoEXT 结构定义如下:
// Provided by VK_EXT_directfb_surface
typedef struct VkDirectFBSurfaceCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkDirectFBSurfaceCreateFlagsEXT flags;
IDirectFB* dfb;
IDirectFBSurface* surface;
} VkDirectFBSurfaceCreateInfoEXT;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
flags保留供将来使用。 -
dfb是指向 DirectFB 的IDirectFB主接口的指针。 -
surface是指向IDirectFBSurface表面接口的指针。
对于 DirectFB,minImageExtent、maxImageExtent 和 currentExtent 必须始终等于表面大小。
// Provided by VK_EXT_directfb_surface
typedef VkFlags VkDirectFBSurfaceCreateFlagsEXT;
VkDirectFBSurfaceCreateFlagsEXT 是一种用于设置掩码的位掩码类型,但目前保留供将来使用。
Fuchsia 平台
要为 Fuchsia ImagePipe 创建 VkSurfaceKHR 对象,请调用:
// Provided by VK_FUCHSIA_imagepipe_surface
VkResult vkCreateImagePipeSurfaceFUCHSIA(
VkInstance instance,
const VkImagePipeSurfaceCreateInfoFUCHSIA* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
-
instance是要与表面关联的实例。 -
pCreateInfo是指向 VkImagePipeSurfaceCreateInfoFUCHSIA 结构的指针,该结构包含影响表面对象创建的参数。 -
pAllocator是当没有更具体的分配器可用时(请参阅 内存分配)用于为 surface 对象分配主机内存的分配器。 -
pSurface是指向 VkSurfaceKHR 句柄的指针,其中返回创建的 surface 对象。
VkImagePipeSurfaceCreateInfoFUCHSIA 结构定义如下:
// Provided by VK_FUCHSIA_imagepipe_surface
typedef struct VkImagePipeSurfaceCreateInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
VkImagePipeSurfaceCreateFlagsFUCHSIA flags;
zx_handle_t imagePipeHandle;
} VkImagePipeSurfaceCreateInfoFUCHSIA;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
flags保留供将来使用。 -
imagePipeHandle是一个zx_handle_t,指向要与表面关联的 ImagePipe。
在 Fuchsia 上,表面 currentExtent 是特殊值 (0xFFFFFFFF, 0xFFFFFFFF),表示表面大小将由面向该表面的交换链的范围确定。
// Provided by VK_FUCHSIA_imagepipe_surface
typedef VkFlags VkImagePipeSurfaceCreateFlagsFUCHSIA;
VkImagePipeSurfaceCreateFlagsFUCHSIA 是一种用于设置掩码的位掩码类型,但目前保留供将来使用。
Google Games 平台
要为 Google Games Platform 流描述符创建 VkSurfaceKHR 对象,请调用:
// Provided by VK_GGP_stream_descriptor_surface
VkResult vkCreateStreamDescriptorSurfaceGGP(
VkInstance instance,
const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
-
instance是要与表面关联的实例。 -
pCreateInfo是指向VkStreamDescriptorSurfaceCreateInfoGGP结构的指针,该结构包含影响表面对象创建的参数。 -
pAllocator是当没有更具体的分配器可用时(请参阅 内存分配)用于为 surface 对象分配主机内存的分配器。 -
pSurface是指向 VkSurfaceKHR 句柄的指针,其中返回创建的 surface 对象。
VkStreamDescriptorSurfaceCreateInfoGGP 结构定义如下:
// Provided by VK_GGP_stream_descriptor_surface
typedef struct VkStreamDescriptorSurfaceCreateInfoGGP {
VkStructureType sType;
const void* pNext;
VkStreamDescriptorSurfaceCreateFlagsGGP flags;
GgpStreamDescriptor streamDescriptor;
} VkStreamDescriptorSurfaceCreateInfoGGP;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
flags保留供将来使用。 -
streamDescriptor是一个GgpStreamDescriptor,指向要与表面关联的 GGP 流描述符。
在 Google Games 平台上,表面范围是动态的。minImageExtent 永远不会大于 1080p,而 maxImageExtent 永远不会小于 1080p。currentExtent 将反映当前的最佳分辨率。
应用程序应在表面的范围内为交换链的 imageExtent 选择合适的大小。使用表面的 currentExtent 将提供最佳的性能和质量。当交换链的 imageExtent 与表面的 currentExtent 不匹配时,如果可能,可呈现的图像会在呈现期间缩放到表面的尺寸,并且返回 VK_SUBOPTIMAL_KHR,否则呈现将失败并返回 VK_ERROR_OUT_OF_DATE_KHR。
// Provided by VK_GGP_stream_descriptor_surface
typedef VkFlags VkStreamDescriptorSurfaceCreateFlagsGGP;
VkStreamDescriptorSurfaceCreateFlagsGGP 是用于设置掩码的位掩码类型,但目前保留供将来使用。
iOS 平台
要为 iOS UIView 或 CAMetalLayer 创建 VkSurfaceKHR 对象,请调用
// Provided by VK_MVK_ios_surface
VkResult vkCreateIOSSurfaceMVK(
VkInstance instance,
const VkIOSSurfaceCreateInfoMVK* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
-
instance是要将表面与之关联的实例。 -
pCreateInfo是指向 VkIOSSurfaceCreateInfoMVK 结构的指针,该结构包含影响表面对象创建的参数。 -
pAllocator是当没有更具体的分配器可用时(请参阅 内存分配)用于为 surface 对象分配主机内存的分配器。 -
pSurface是指向 VkSurfaceKHR 句柄的指针,其中返回创建的 surface 对象。
|
|
VkIOSSurfaceCreateInfoMVK 结构的定义如下
// Provided by VK_MVK_ios_surface
typedef struct VkIOSSurfaceCreateInfoMVK {
VkStructureType sType;
const void* pNext;
VkIOSSurfaceCreateFlagsMVK flags;
const void* pView;
} VkIOSSurfaceCreateInfoMVK;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
flags保留供将来使用。 -
pView是对CAMetalLayer对象或UIView对象的引用。
// Provided by VK_MVK_ios_surface
typedef VkFlags VkIOSSurfaceCreateFlagsMVK;
VkIOSSurfaceCreateFlagsMVK 是用于设置掩码的位掩码类型,但目前保留供将来使用。
macOS 平台
要为 macOS NSView 或 CAMetalLayer 创建 VkSurfaceKHR 对象,请调用
// Provided by VK_MVK_macos_surface
VkResult vkCreateMacOSSurfaceMVK(
VkInstance instance,
const VkMacOSSurfaceCreateInfoMVK* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
-
instance是要将表面与之关联的实例。 -
pCreateInfo是指向 VkMacOSSurfaceCreateInfoMVK 结构的指针,该结构包含影响表面对象创建的参数。 -
pAllocator是当没有更具体的分配器可用时(请参阅 内存分配)用于为 surface 对象分配主机内存的分配器。 -
pSurface是指向 VkSurfaceKHR 句柄的指针,其中返回创建的 surface 对象。
|
|
VkMacOSSurfaceCreateInfoMVK 结构的定义如下
// Provided by VK_MVK_macos_surface
typedef struct VkMacOSSurfaceCreateInfoMVK {
VkStructureType sType;
const void* pNext;
VkMacOSSurfaceCreateFlagsMVK flags;
const void* pView;
} VkMacOSSurfaceCreateInfoMVK;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
flags保留供将来使用。 -
pView是对CAMetalLayer对象或NSView对象的引用。
// Provided by VK_MVK_macos_surface
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
VkMacOSSurfaceCreateFlagsMVK 是用于设置掩码的位掩码类型,但目前保留供将来使用。
VI 平台
要为 nn::vi::Layer 创建 VkSurfaceKHR 对象,请使用 nn::vi::GetNativeWindow 查询图层的原生句柄,然后调用
// Provided by VK_NN_vi_surface
VkResult vkCreateViSurfaceNN(
VkInstance instance,
const VkViSurfaceCreateInfoNN* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
-
instance是要将表面与之关联的实例。 -
pCreateInfo是指向VkViSurfaceCreateInfoNN结构的指针,该结构包含影响表面对象创建的参数。 -
pAllocator是当没有更具体的分配器可用时(请参阅 内存分配)用于为 surface 对象分配主机内存的分配器。 -
pSurface是指向 VkSurfaceKHR 句柄的指针,其中返回创建的 surface 对象。
在使用特定 nn::vi::NativeWindowHandle 创建的表面的生命周期内,应用程序必须不要尝试为同一 nn::vi::Layer 创建另一个表面,也不要尝试通过其他平台机制连接到同一 nn::vi::Layer。
如果使用指定的大小创建原生窗口,则 currentExtent 将反映该大小。在这种情况下,应用程序应为交换链的 imageExtent 使用相同的大小。否则,currentExtent 将具有特殊值 (0xFFFFFFFF, 0xFFFFFFFF),表示应用程序应为交换链的 imageExtent 选择合适的大小(例如,通过匹配对 nn::vi::GetDisplayResolution 的调用结果)。
VkViSurfaceCreateInfoNN 结构定义如下:
// Provided by VK_NN_vi_surface
typedef struct VkViSurfaceCreateInfoNN {
VkStructureType sType;
const void* pNext;
VkViSurfaceCreateFlagsNN flags;
void* window;
} VkViSurfaceCreateInfoNN;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
flags保留供将来使用。 -
window是nn::vi::Layer的nn::vi::NativeWindowHandle,用于将该 surface 与之关联。
// Provided by VK_NN_vi_surface
typedef VkFlags VkViSurfaceCreateFlagsNN;
VkViSurfaceCreateFlagsNN 是用于设置掩码的位掩码类型,但目前保留供将来使用。
Metal 平台
要为 CAMetalLayer 创建一个 VkSurfaceKHR 对象,请调用
// Provided by VK_EXT_metal_surface
VkResult vkCreateMetalSurfaceEXT(
VkInstance instance,
const VkMetalSurfaceCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
-
instance是要将表面与之关联的实例。 -
pCreateInfo是一个指向 VkMetalSurfaceCreateInfoEXT 结构的指针,该结构指定影响 surface 对象创建的参数。 -
pAllocator是当没有更具体的分配器可用时(请参阅 内存分配)用于为 surface 对象分配主机内存的分配器。 -
pSurface是一个指向VkSurfaceKHR句柄的指针,创建的 surface 对象将返回到该句柄中。
VkMetalSurfaceCreateInfoEXT 结构定义如下:
// Provided by VK_EXT_metal_surface
typedef struct VkMetalSurfaceCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkMetalSurfaceCreateFlagsEXT flags;
const CAMetalLayer* pLayer;
} VkMetalSurfaceCreateInfoEXT;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
flags保留供将来使用。 -
pLayer是一个指向CAMetalLayer对象的引用,该对象表示可渲染的 surface。
为了移除不必要的编译时依赖,Vulkan 头文件中提供了 CAMetalLayer 的不完整类型定义。
// Provided by VK_EXT_metal_surface
#ifdef __OBJC__
@class CAMetalLayer;
#else
typedef void CAMetalLayer;
#endif
实际的 CAMetalLayer 类型在 QuartzCore 框架中定义。
// Provided by VK_EXT_metal_surface
typedef VkFlags VkMetalSurfaceCreateFlagsEXT;
VkMetalSurfaceCreateFlagsEXT 是用于设置掩码的位掩码类型,但目前保留供将来使用。
QNX Screen 平台
要为 QNX Screen surface 创建一个 VkSurfaceKHR 对象,请调用
// Provided by VK_QNX_screen_surface
VkResult vkCreateScreenSurfaceQNX(
VkInstance instance,
const VkScreenSurfaceCreateInfoQNX* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
-
instance是与 surface 关联的实例。 -
pCreateInfo是一个指向 VkScreenSurfaceCreateInfoQNX 结构的指针,该结构包含影响 surface 对象创建的参数。 -
pAllocator是当没有更具体的分配器可用时(请参阅 内存分配)用于为 surface 对象分配主机内存的分配器。 -
pSurface是指向 VkSurfaceKHR 句柄的指针,其中返回创建的 surface 对象。
VkScreenSurfaceCreateInfoQNX 结构定义如下:
// Provided by VK_QNX_screen_surface
typedef struct VkScreenSurfaceCreateInfoQNX {
VkStructureType sType;
const void* pNext;
VkScreenSurfaceCreateFlagsQNX flags;
struct _screen_context* context;
struct _screen_window* window;
} VkScreenSurfaceCreateInfoQNX;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
flags保留供将来使用。 -
context和window是 QNX Screen 的context和window,用于将该 surface 与之关联。
// Provided by VK_QNX_screen_surface
typedef VkFlags VkScreenSurfaceCreateFlagsQNX;
VkScreenSurfaceCreateFlagsQNX 是用于设置掩码的位掩码类型,但目前保留供将来使用。
平台无关信息
一旦创建,VkSurfaceKHR 对象可以在此扩展和其他扩展中使用,特别是 VK_KHR_swapchain 扩展。
如果 surface 不再可用,一些 WSI 函数会返回 VK_ERROR_SURFACE_LOST_KHR。在此错误发生后,surface(以及任何子交换链,如果存在)应该被销毁,因为没有办法将它们恢复到未丢失的状态。应用程序可以尝试使用相同的本地平台窗口对象创建一个新的 VkSurfaceKHR,但是这种重新创建是否会成功取决于平台,并且可能取决于 surface 变得不可用的原因。丢失的 surface 不会导致设备丢失。
要销毁一个 VkSurfaceKHR 对象,请调用
// Provided by VK_KHR_surface
void vkDestroySurfaceKHR(
VkInstance instance,
VkSurfaceKHR surface,
const VkAllocationCallbacks* pAllocator);
-
instance是用于创建 surface 的实例。 -
surface是要销毁的 surface。 -
pAllocator是当没有更具体的分配器可用时(请参阅 内存分配)用于为 surface 对象分配主机内存的分配器。
销毁一个 VkSurfaceKHR 只是切断了 Vulkan 和本地 surface 之间的连接,并不意味着销毁本地 surface、关闭窗口或类似的行为。
直接呈现到显示设备
在某些环境中,应用程序可以直接将 Vulkan 渲染结果呈现到显示设备,而无需使用中间窗口系统。这对于嵌入式应用程序或使用 Vulkan 实现窗口系统的渲染/呈现后端非常有用。VK_KHR_display 扩展提供了枚举显示设备并创建针对显示的 VkSurfaceKHR 对象所需的功能。
显示枚举
显示器由 VkDisplayKHR 句柄表示。
// Provided by VK_KHR_display
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayKHR)
提供了各种函数来枚举 Vulkan 物理设备上可用的显示设备。要查询有关可用显示器的信息,请调用
// Provided by VK_KHR_display
VkResult vkGetPhysicalDeviceDisplayPropertiesKHR(
VkPhysicalDevice physicalDevice,
uint32_t* pPropertyCount,
VkDisplayPropertiesKHR* pProperties);
-
physicalDevice是一个物理设备。 -
pPropertyCount是一个指向整数的指针,该整数与可用或查询的显示设备数量有关,如下所述。 -
pProperties可以是NULL或指向 VkDisplayPropertiesKHR 结构数组的指针。
如果 pProperties 为 NULL,则 physicalDevice 可用的显示设备数量将在 pPropertyCount 中返回。否则,pPropertyCount 必须指向由应用程序设置为 pProperties 数组中元素数量的变量,并且在返回时,该变量将被实际写入 pProperties 的结构数量覆盖。如果 pPropertyCount 的值小于 physicalDevice 的显示设备数量,则最多写入 pPropertyCount 个结构,并且将返回 VK_INCOMPLETE 而不是 VK_SUCCESS,以指示并非所有可用属性都已返回。
VkDisplayPropertiesKHR 结构的定义如下
// Provided by VK_KHR_display
typedef struct VkDisplayPropertiesKHR {
VkDisplayKHR display;
const char* displayName;
VkExtent2D physicalDimensions;
VkExtent2D physicalResolution;
VkSurfaceTransformFlagsKHR supportedTransforms;
VkBool32 planeReorderPossible;
VkBool32 persistentContent;
} VkDisplayPropertiesKHR;
-
display是一个句柄,用于引用此处描述的显示器。此句柄在 Vulkan 实例的生命周期内有效。 -
displayName为NULL或指向包含显示器名称的以 null 结尾的 UTF-8 字符串的指针。通常,这将是显示器的 EDID 提供的名称。如果为NULL,则没有合适的名称可用。如果不为NULL,则指向的字符串 必须 在display有效时保持可访问且未修改。 -
physicalDimensions描述显示器可见部分的物理宽度和高度(以毫米为单位)。 -
physicalResolution描述显示器的物理、原生或首选分辨率。
|
对于没有自然值可在此处返回的设备,实现 应该 返回支持的最大分辨率。 |
-
supportedTransforms是一个 VkSurfaceTransformFlagBitsKHR 的位掩码,描述了此显示器支持的变换。 -
planeReorderPossible指示此显示器上的平面是否 可以 更改其 z 顺序。如果此值为VK_TRUE,则应用程序 可以 相对于彼此以任何顺序重新排列此显示器上的平面。 -
persistentContent指示显示器是否支持自刷新/内部缓冲。如果此值为 true,则应用程序 可以 对针对此显示器创建的交换链提交持久呈现操作。
|
当屏幕内容不频繁更新,或者在大多数帧中只需要更新屏幕的一部分时,持久呈现 可能 具有更高的延迟,并且 可能 使用更少的功率。 |
要查询有关可用显示器的信息,请调用
// Provided by VK_KHR_get_display_properties2
VkResult vkGetPhysicalDeviceDisplayProperties2KHR(
VkPhysicalDevice physicalDevice,
uint32_t* pPropertyCount,
VkDisplayProperties2KHR* pProperties);
-
physicalDevice是一个物理设备。 -
pPropertyCount是一个指向整数的指针,该整数与可用或查询的显示设备数量有关,如下所述。 -
pProperties可以是NULL或指向VkDisplayProperties2KHR结构数组的指针。
vkGetPhysicalDeviceDisplayProperties2KHR 的行为类似于 vkGetPhysicalDeviceDisplayPropertiesKHR,但可以通过链接的输出结构返回扩展信息。
VkDisplayProperties2KHR 结构的定义如下
// Provided by VK_KHR_get_display_properties2
typedef struct VkDisplayProperties2KHR {
VkStructureType sType;
void* pNext;
VkDisplayPropertiesKHR displayProperties;
} VkDisplayProperties2KHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
displayProperties是一个 VkDisplayPropertiesKHR 结构。
获取和释放显示器
在某些平台上,对显示器的访问仅限于单个进程或本机驱动程序实例。在这样的平台上,如果某些或全部显示器已被本机窗口系统或其他应用程序使用,则它们可能对 Vulkan 不可用。
要从 X11 服务器获取在 Vulkan 中直接访问显示器的权限,请调用
// Provided by VK_EXT_acquire_xlib_display
VkResult vkAcquireXlibDisplayEXT(
VkPhysicalDevice physicalDevice,
Display* dpy,
VkDisplayKHR display);
-
physicalDevice显示器所在的物理设备。 -
dpy与当前拥有display的 X11 服务器的连接。 -
display调用者希望在 Vulkan 中控制的显示器。
控制显示器所需的所有权限都授予与 physicalDevice 关联的 Vulkan 实例,直到显示器被释放或由 dpy 指定的 X11 连接终止。当从中获取控制权的 X11 服务器本身失去对 display 的访问权限时,访问显示器的权限 可能 会被临时撤销。在此期间,需要访问显示器的操作 必须 失败,并返回相应的错误代码。如果与 dpy 关联的 X11 服务器不拥有 display,或者访问它的权限已被另一个实体获取,则调用 必须 返回错误代码 VK_ERROR_INITIALIZATION_FAILED。
|
X11 服务器失去对显示器访问权限的一个示例是当它失去对其虚拟终端的所有权时。 |
当从 X11 服务器获取显示器时,应用程序可能还希望使用本机句柄而不是 VkDisplayKHR 句柄来枚举和识别它们。要确定与 X11 RandR 输出对应的 VkDisplayKHR 句柄,请调用
// Provided by VK_EXT_acquire_xlib_display
VkResult vkGetRandROutputDisplayEXT(
VkPhysicalDevice physicalDevice,
Display* dpy,
RROutput rrOutput,
VkDisplayKHR* pDisplay);
-
physicalDevice用于查询显示句柄的物理设备。 -
dpy从中查询rrOutput的 X11 服务器的连接。 -
rrOutputX11 RandR 输出 ID。 -
pDisplay此处将返回相应的 VkDisplayKHR 句柄。
如果 physicalDevice 上没有与 rrOutput 对应的 VkDisplayKHR,则 必须 在 pDisplay 中返回 VK_NULL_HANDLE。
要在 Windows 10 上获取直接访问 Vulkan 中显示器的权限,请调用
// Provided by VK_NV_acquire_winrt_display
VkResult vkAcquireWinrtDisplayNV(
VkPhysicalDevice physicalDevice,
VkDisplayKHR display);
-
physicalDevice显示器所在的物理设备。 -
display调用者希望在 Vulkan 中控制的显示器。
控制显示器所需的所有权限都授予与 physicalDevice 关联的 Vulkan 实例,直到显示器被释放或应用程序终止。访问显示器的权限可能会被导致 Windows 10 本身失去对 display 的访问权限的事件撤销。如果发生这种情况,需要访问显示器的操作必须失败并返回相应的错误代码。如果访问 display 的权限已被另一个实体获取,则调用必须返回错误代码 VK_ERROR_INITIALIZATION_FAILED。
|
Vulkan 实例通过执行类似于 “winrt::Windows::Devices::Display::Core::DisplayManager.TryAcquireTarget()” 在“DisplayTarget”上的操作来获得对 “winrt::Windows::Devices::Display::Core::DisplayTarget” 的控制权。 |
|
Windows 10 失去对显示器访问权限的一个例子是显示器被热插拔。 |
|
显示器已被另一个实体获取的一个例子是 Windows 桌面合成器 (DWM) 控制显示器。从 Windows 10 版本 2004 开始,可以使用“显示设置”控制面板的“高级显示设置”子页面来使 DWM 释放显示器。vkAcquireWinrtDisplayNV 本身不会导致 DWM 释放显示器;此操作必须在 Vulkan 之外执行。 |
当在 Windows 10 上获取显示器时,应用程序可能还希望使用本机句柄而不是 VkDisplayKHR 句柄来枚举和识别它们。
要确定与 “winrt::Windows::Devices::Display::Core::DisplayTarget” 对应的 VkDisplayKHR 句柄,请调用
// Provided by VK_NV_acquire_winrt_display
VkResult vkGetWinrtDisplayNV(
VkPhysicalDevice physicalDevice,
uint32_t deviceRelativeId,
VkDisplayKHR* pDisplay);
-
physicalDevice要在其上查询显示句柄的物理设备。 -
deviceRelativeId“AdapterRelativeId” 属性的值,该属性由具有与physicalDevice的 VkPhysicalDeviceIDProperties 的deviceLUID属性匹配的 “Id” 属性的 “DisplayAdapter” 枚举的 “DisplayTarget”。 -
pDisplay此处将返回相应的 VkDisplayKHR 句柄。
如果 physicalDevice 上没有与 deviceRelativeId 对应的 VkDisplayKHR,则 必须 在 pDisplay 中返回 VK_NULL_HANDLE。
要从直接渲染管理器 (DRM) 接口获取直接 Vulkan 中显示器的权限,请调用
// Provided by VK_EXT_acquire_drm_display
VkResult vkAcquireDrmDisplayEXT(
VkPhysicalDevice physicalDevice,
int32_t drmFd,
VkDisplayKHR display);
-
physicalDevice显示器所在的物理设备。 -
drmFdDRM 主文件描述符。 -
display调用者希望 Vulkan 控制的显示器。
控制显示器所需的所有权限都授予与提供的 physicalDevice 关联的 Vulkan 实例,直到显示器被释放或连接器被拔下。提供的 drmFd 必须与 physicalDevice 拥有的相对应。如果不是,则必须返回错误代码 VK_ERROR_UNKNOWN。DRM FD 必须具有 DRM 主权限。如果在获取显示器期间遇到任何错误,则调用必须返回错误代码 VK_ERROR_INITIALIZATION_FAILED。
在释放显示器之前,不应关闭提供的 DRM fd,尝试这样做可能会导致未定义的行为。
在从 DRM 接口获取显示器之前,调用者可能希望通过使用 connectorId 标识特定的 VkDisplayKHR 句柄来选择它。为此,请调用
// Provided by VK_EXT_acquire_drm_display
VkResult vkGetDrmDisplayEXT(
VkPhysicalDevice physicalDevice,
int32_t drmFd,
uint32_t connectorId,
VkDisplayKHR* display);
-
physicalDevice用于查询显示器的物理设备。 -
drmFdDRM 主文件描述符。 -
connectorId指定的 DRM 连接器的标识符。 -
display相应的 VkDisplayKHR 句柄将在此处返回。
如果在 physicalDevice 上没有与 connectorId 对应的 VkDisplayKHR,则返回的 display 必须为 VK_NULL_HANDLE。提供的 drmFd 必须与 physicalDevice 所拥有的 drmFd 相对应。否则,必须返回错误代码 VK_ERROR_UNKNOWN。不需要主权限,因为文件描述符仅用于信息收集目的。给定的 connectorId 必须是提供的 drmFd 所拥有的资源。否则,必须返回错误代码 VK_ERROR_UNKNOWN。如果在显示器识别过程中遇到任何错误,则调用必须返回错误代码 VK_ERROR_INITIALIZATION_FAILED。
要释放先前获取的显示器,请调用
// Provided by VK_EXT_direct_mode_display
VkResult vkReleaseDisplayEXT(
VkPhysicalDevice physicalDevice,
VkDisplayKHR display);
-
physicalDevice显示器所在的物理设备。 -
display要释放控制权的显示器。
显示平面
图像被呈现到显示器上的各个平面。设备必须支持每个显示器上至少一个平面。平面可以堆叠和混合,以在一个显示器上合成多个图像。设备可能仅支持固定的堆叠顺序和平面与显示器之间的固定映射,或者它们可能允许任意应用程序指定的堆叠顺序以及平面与显示器之间的映射。要查询设备显示平面的属性,请调用
// Provided by VK_KHR_display
VkResult vkGetPhysicalDeviceDisplayPlanePropertiesKHR(
VkPhysicalDevice physicalDevice,
uint32_t* pPropertyCount,
VkDisplayPlanePropertiesKHR* pProperties);
-
physicalDevice是一个物理设备。 -
pPropertyCount是一个指向与可用或查询的显示平面数量相关的整数的指针,如下所述。 -
pProperties可以是NULL,也可以是指向VkDisplayPlanePropertiesKHR结构数组的指针。
如果 pProperties 为 NULL,则 physicalDevice 可用的显示平面数量将在 pPropertyCount 中返回。否则,pPropertyCount 必须指向由应用程序设置为 pProperties 数组中元素数量的变量,并且在返回时,该变量将覆盖为实际写入 pProperties 的结构数量。如果 pPropertyCount 的值小于 physicalDevice 的显示平面数量,则最多写入 pPropertyCount 个结构。
VkDisplayPlanePropertiesKHR 结构定义为
// Provided by VK_KHR_display
typedef struct VkDisplayPlanePropertiesKHR {
VkDisplayKHR currentDisplay;
uint32_t currentStackIndex;
} VkDisplayPlanePropertiesKHR;
-
currentDisplay是该平面当前关联的显示器的句柄。如果该平面当前未附加到任何显示器,则此值将为 VK_NULL_HANDLE。 -
currentStackIndex是该平面当前的 z 顺序。它将在 0 和vkGetPhysicalDeviceDisplayPlanePropertiesKHR在pPropertyCount中返回的值之间。
要查询设备显示平面的属性,请调用
// Provided by VK_KHR_get_display_properties2
VkResult vkGetPhysicalDeviceDisplayPlaneProperties2KHR(
VkPhysicalDevice physicalDevice,
uint32_t* pPropertyCount,
VkDisplayPlaneProperties2KHR* pProperties);
-
physicalDevice是一个物理设备。 -
pPropertyCount是一个指向与可用或查询的显示平面数量相关的整数的指针,如下所述。 -
pProperties可以是NULL,也可以是指向VkDisplayPlaneProperties2KHR结构数组的指针。
vkGetPhysicalDeviceDisplayPlaneProperties2KHR 的行为类似于 vkGetPhysicalDeviceDisplayPlanePropertiesKHR,但可以通过链式输出结构返回扩展信息。
VkDisplayPlaneProperties2KHR 结构定义为
// Provided by VK_KHR_get_display_properties2
typedef struct VkDisplayPlaneProperties2KHR {
VkStructureType sType;
void* pNext;
VkDisplayPlanePropertiesKHR displayPlaneProperties;
} VkDisplayPlaneProperties2KHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
displayPlaneProperties是一个 VkDisplayPlanePropertiesKHR 结构。
要确定平面可与哪些显示器一起使用,请调用
// Provided by VK_KHR_display
VkResult vkGetDisplayPlaneSupportedDisplaysKHR(
VkPhysicalDevice physicalDevice,
uint32_t planeIndex,
uint32_t* pDisplayCount,
VkDisplayKHR* pDisplays);
-
physicalDevice是一个物理设备。 -
planeIndex是应用程序希望使用的平面,必须在 [0, 物理设备平面数量 - 1] 范围内。 -
pDisplayCount是一个指向与可用或查询的显示器数量相关的整数的指针,如下所述。 -
pDisplays可以是NULL,也可以是指向VkDisplayKHR句柄数组的指针。
如果 pDisplays 为 NULL,则 physicalDevice 的指定 planeIndex 可用的显示器数量将在 pDisplayCount 中返回。否则,pDisplayCount 必须指向由应用程序设置为 pDisplays 数组中元素数量的变量,并且在返回时,该变量将覆盖为实际写入 pDisplays 的句柄数量。如果 pDisplayCount 的值小于 physicalDevice 可用的显示平面对的数量,则最多写入 pDisplayCount 个句柄,并且将返回 VK_INCOMPLETE 而不是 VK_SUCCESS,以表明并非所有可用对都已返回。
可以使用专门的查询函数来查询显示器的其他属性。
显示模式
显示模式由 VkDisplayModeKHR 句柄表示。
// Provided by VK_KHR_display
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayModeKHR)
每个显示器默认都关联一个或多个支持的模式。这些内置模式通过调用以下函数进行查询:
// Provided by VK_KHR_display
VkResult vkGetDisplayModePropertiesKHR(
VkPhysicalDevice physicalDevice,
VkDisplayKHR display,
uint32_t* pPropertyCount,
VkDisplayModePropertiesKHR* pProperties);
-
physicalDevice是与display关联的物理设备。 -
display是要查询的显示器。 -
pPropertyCount是一个指向整数的指针,该整数与可用或查询的显示模式的数量相关,如下所述。 -
pProperties可以是NULL,也可以是指向VkDisplayModePropertiesKHR结构体数组的指针。
如果 pProperties 为 NULL,则 physicalDevice 指定的 display 上可用的显示模式数量将在 pPropertyCount 中返回。否则,pPropertyCount 必须指向一个由应用程序设置为 pProperties 数组中元素数量的变量,并且在返回时,该变量将被实际写入到 pProperties 的结构体数量覆盖。如果 pPropertyCount 的值小于 physicalDevice 的显示模式数量,则最多会写入 pPropertyCount 个结构体,并且会返回 VK_INCOMPLETE 而不是 VK_SUCCESS,以指示并非所有可用的显示模式都被返回。
VkDisplayModePropertiesKHR 结构体的定义如下:
// Provided by VK_KHR_display
typedef struct VkDisplayModePropertiesKHR {
VkDisplayModeKHR displayMode;
VkDisplayModeParametersKHR parameters;
} VkDisplayModePropertiesKHR;
-
displayMode是指向此结构体中描述的显示模式的句柄。此句柄在 Vulkan 实例的生命周期内有效。 -
parameters是一个 VkDisplayModeParametersKHR 结构体,描述与displayMode关联的显示参数。
// Provided by VK_KHR_display
typedef VkFlags VkDisplayModeCreateFlagsKHR;
VkDisplayModeCreateFlagsKHR 是用于设置掩码的位掩码类型,但目前保留供将来使用。
要查询设备内置显示模式的属性,请调用以下函数:
// Provided by VK_KHR_get_display_properties2
VkResult vkGetDisplayModeProperties2KHR(
VkPhysicalDevice physicalDevice,
VkDisplayKHR display,
uint32_t* pPropertyCount,
VkDisplayModeProperties2KHR* pProperties);
-
physicalDevice是与display关联的物理设备。 -
display是要查询的显示器。 -
pPropertyCount是一个指向整数的指针,该整数与可用或查询的显示模式的数量相关,如下所述。 -
pProperties可以是NULL,也可以是指向VkDisplayModeProperties2KHR结构体数组的指针。
vkGetDisplayModeProperties2KHR 的行为类似于 vkGetDisplayModePropertiesKHR,但能够通过链式输出结构体返回扩展信息。
VkDisplayModeProperties2KHR 结构体的定义如下:
// Provided by VK_KHR_get_display_properties2
typedef struct VkDisplayModeProperties2KHR {
VkStructureType sType;
void* pNext;
VkDisplayModePropertiesKHR displayModeProperties;
} VkDisplayModeProperties2KHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
displayModeProperties是一个 VkDisplayModePropertiesKHR 结构体。
VkDisplayModeParametersKHR 结构体的定义如下:
// Provided by VK_KHR_display
typedef struct VkDisplayModeParametersKHR {
VkExtent2D visibleRegion;
uint32_t refreshRate;
} VkDisplayModeParametersKHR;
-
visibleRegion是可见区域的 2D 范围。 -
refreshRate是一个uint32_t类型的值,表示显示器每秒刷新的次数乘以 1000。
|
例如,一个 60Hz 的显示模式将报告 |
VkDisplayModeStereoPropertiesNV 结构体的定义如下:
// Provided by VK_NV_display_stereo
typedef struct VkDisplayModeStereoPropertiesNV {
VkStructureType sType;
const void* pNext;
VkBool32 hdmi3DSupported;
} VkDisplayModeStereoPropertiesNV;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
hdmi3DSupported指示此显示模式是否可以用于配置为VK_DISPLAY_SURFACE_STEREO_TYPE_HDMI_3D_NV的显示表面。
还可以通过调用以下函数来创建其他模式:
// Provided by VK_KHR_display
VkResult vkCreateDisplayModeKHR(
VkPhysicalDevice physicalDevice,
VkDisplayKHR display,
const VkDisplayModeCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkDisplayModeKHR* pMode);
-
physicalDevice是与display关联的物理设备。 -
display是要为其创建其他模式的显示器。 -
pCreateInfo是指向 VkDisplayModeCreateInfoKHR 结构体的指针,该结构体描述要创建的新模式。 -
pAllocator是在没有更具体的分配器可用时,用于为显示模式对象分配主机内存的分配器(请参阅内存分配)。 -
pMode是指向 VkDisplayModeKHR 句柄的指针,创建的模式将在此句柄中返回。
VkDisplayModeCreateInfoKHR 结构的定义如下:
// Provided by VK_KHR_display
typedef struct VkDisplayModeCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkDisplayModeCreateFlagsKHR flags;
VkDisplayModeParametersKHR parameters;
} VkDisplayModeCreateInfoKHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
flags保留供将来使用,并且必须为零。 -
parameters是一个 VkDisplayModeParametersKHR 结构,描述用于创建新模式的显示参数。如果参数与指定的显示不兼容,则实现必须返回VK_ERROR_INITIALIZATION_FAILED。
希望直接呈现到显示的应用程序必须选择他们希望定位的显示图层或“平面”,以及与显示一起使用的模式。每个显示至少支持一个平面。给定模式和平面组合的功能通过调用以下函数确定:
// Provided by VK_KHR_display
VkResult vkGetDisplayPlaneCapabilitiesKHR(
VkPhysicalDevice physicalDevice,
VkDisplayModeKHR mode,
uint32_t planeIndex,
VkDisplayPlaneCapabilitiesKHR* pCapabilities);
-
physicalDevice是与mode指定的显示相关联的物理设备 -
mode是应用程序打算在使用指定平面时编程的显示模式。请注意,此参数还隐含地指定了一个显示。 -
planeIndex是应用程序打算与显示一起使用的平面,并且小于设备支持的显示平面的数量。 -
pCapabilities是指向 VkDisplayPlaneCapabilitiesKHR 结构的指针,功能将在此结构中返回。
VkDisplayPlaneCapabilitiesKHR 结构的定义如下:
// Provided by VK_KHR_display
typedef struct VkDisplayPlaneCapabilitiesKHR {
VkDisplayPlaneAlphaFlagsKHR supportedAlpha;
VkOffset2D minSrcPosition;
VkOffset2D maxSrcPosition;
VkExtent2D minSrcExtent;
VkExtent2D maxSrcExtent;
VkOffset2D minDstPosition;
VkOffset2D maxDstPosition;
VkExtent2D minDstExtent;
VkExtent2D maxDstExtent;
} VkDisplayPlaneCapabilitiesKHR;
-
supportedAlpha是 VkDisplayPlaneAlphaFlagBitsKHR 的位掩码,描述了支持的 alpha 混合模式。 -
minSrcPosition是此平面使用指定模式支持的最小源矩形偏移量。 -
maxSrcPosition是此平面使用指定模式支持的最大源矩形偏移量。maxSrcPosition的x和y分量必须分别大于或等于minSrcPosition的x和y分量。 -
minSrcExtent是此平面使用指定模式支持的最小源矩形大小。 -
maxSrcExtent是此平面使用指定模式支持的最大源矩形大小。 -
minDstPosition、maxDstPosition、minDstExtent、maxDstExtent都具有与其相应的*Src*等效项相似的语义,但适用于模式内的输出区域,而不是源图像内的输入区域。与*Src*偏移量不同,minDstPosition和maxDstPosition可以包含负值。
最小和最大位置和范围字段描述了实现限制(如果有),因为它们适用于指定的显示模式和平面。供应商可以支持在指定的显示平面上显示交换链的可呈现图像的子集。这通过返回 minSrcPosition、maxSrcPosition、minSrcExtent 和 maxSrcExtent 值来表示,这些值指示可能的位置和大小范围,这些位置和大小范围可以用于指定在指定显示模式和平面上创建交换链时将从中读取源像素的可呈现图像内的区域。
供应商也可以支持将可呈现图像的内容映射到指定显示模式中可见区域的子集或超集。这通过返回 minDstPosition、maxDstPosition、minDstExtent 和 maxDstExtent 值来表示,这些值指示可能的位置和大小范围,这些位置和大小范围可以用于描述源像素将映射到的显示模式内的区域。
其他供应商可以仅支持可呈现图像中的像素与显示模式之间的 1 对 1 映射。这可以通过返回 minSrcPosition、maxSrcPosition、minDstPosition 和 maxDstPosition 的 (0,0),以及 minSrcExtent、maxSrcExtent、minDstExtent 和 maxDstExtent 的(显示模式宽度,显示模式高度)来表示。
supportedAlpha 值必须至少包含一个有效的 VkDisplayPlaneAlphaFlagBitsKHR 位。
这些值表示实现各个字段的限制。并非 VkDisplayPlaneCapabilitiesKHR 中返回的偏移量和范围内的所有值组合都保证受支持。指定不受支持的组合的演示请求可能会失败。
要查询给定模式和平面组合的功能,请调用
// Provided by VK_KHR_get_display_properties2
VkResult vkGetDisplayPlaneCapabilities2KHR(
VkPhysicalDevice physicalDevice,
const VkDisplayPlaneInfo2KHR* pDisplayPlaneInfo,
VkDisplayPlaneCapabilities2KHR* pCapabilities);
-
physicalDevice是与pDisplayPlaneInfo关联的物理设备。 -
pDisplayPlaneInfo是指向 VkDisplayPlaneInfo2KHR 结构的指针,该结构描述了平面和模式。 -
pCapabilities是指向 VkDisplayPlaneCapabilities2KHR 结构的指针,功能将在此结构中返回。
vkGetDisplayPlaneCapabilities2KHR 的行为类似于 vkGetDisplayPlaneCapabilitiesKHR,它能够通过链接的输入结构指定扩展输入,并通过链接的输出结构返回扩展信息。
VkDisplayPlaneInfo2KHR 结构的定义如下:
// Provided by VK_KHR_get_display_properties2
typedef struct VkDisplayPlaneInfo2KHR {
VkStructureType sType;
const void* pNext;
VkDisplayModeKHR mode;
uint32_t planeIndex;
} VkDisplayPlaneInfo2KHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
mode是应用程序打算在使用指定平面时编程的显示模式。
|
此参数还隐式地指定了一个显示器。 |
-
planeIndex是应用程序打算与显示器一起使用的平面。
VkDisplayPlaneInfo2KHR 的成员对应于 vkGetDisplayPlaneCapabilitiesKHR 的参数,添加了 sType 和 pNext 以实现可扩展性。
VkDisplayPlaneCapabilities2KHR 结构的定义如下:
// Provided by VK_KHR_get_display_properties2
typedef struct VkDisplayPlaneCapabilities2KHR {
VkStructureType sType;
void* pNext;
VkDisplayPlaneCapabilitiesKHR capabilities;
} VkDisplayPlaneCapabilities2KHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
capabilities是一个 VkDisplayPlaneCapabilitiesKHR 结构。
显示控制
要设置显示器的电源状态,请调用:
// Provided by VK_EXT_display_control
VkResult vkDisplayPowerControlEXT(
VkDevice device,
VkDisplayKHR display,
const VkDisplayPowerInfoEXT* pDisplayPowerInfo);
-
device是与display关联的逻辑设备。 -
display是要修改其电源状态的显示器。 -
pDisplayPowerInfo是指向 VkDisplayPowerInfoEXT 结构的指针,该结构指定了display的新电源状态。
VkDisplayPowerInfoEXT 结构的定义如下:
// Provided by VK_EXT_display_control
typedef struct VkDisplayPowerInfoEXT {
VkStructureType sType;
const void* pNext;
VkDisplayPowerStateEXT powerState;
} VkDisplayPowerInfoEXT;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
powerState是一个 VkDisplayPowerStateEXT 值,指定显示器的新电源状态。
VkDisplayPowerInfoEXT::powerState 的可能值,指定显示器的新电源状态为:
// Provided by VK_EXT_display_control
typedef enum VkDisplayPowerStateEXT {
VK_DISPLAY_POWER_STATE_OFF_EXT = 0,
VK_DISPLAY_POWER_STATE_SUSPEND_EXT = 1,
VK_DISPLAY_POWER_STATE_ON_EXT = 2,
} VkDisplayPowerStateEXT;
-
VK_DISPLAY_POWER_STATE_OFF_EXT指定显示器已断电。 -
VK_DISPLAY_POWER_STATE_SUSPEND_EXT指定显示器进入低功耗模式,在此模式下,它可能能够比处于VK_DISPLAY_POWER_STATE_OFF_EXT状态时更快地转换回VK_DISPLAY_POWER_STATE_ON_EXT。此状态可能与VK_DISPLAY_POWER_STATE_OFF_EXT相同。 -
VK_DISPLAY_POWER_STATE_ON_EXT指定显示器已通电。
显示表面
完整的显示配置包括一个模式、一个或多个显示平面以及描述其行为的任何参数,以及描述与这些平面关联的图像的某些方面的参数。显示表面描述了完整显示配置中单个平面的配置。要为显示平面创建 VkSurfaceKHR 对象,请调用:
// Provided by VK_KHR_display
VkResult vkCreateDisplayPlaneSurfaceKHR(
VkInstance instance,
const VkDisplaySurfaceCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
-
instance是与目标显示器所在的物理设备对应的实例。 -
pCreateInfo是指向 VkDisplaySurfaceCreateInfoKHR 结构的指针,该结构指定要使用的模式、平面和其他参数,如下所述。 -
pAllocator是当没有更具体的分配器可用时(请参阅 内存分配)用于为 surface 对象分配主机内存的分配器。 -
pSurface是指向 VkSurfaceKHR 句柄的指针,将在其中返回创建的表面。
VkDisplaySurfaceCreateInfoKHR 结构的定义如下:
// Provided by VK_KHR_display
typedef struct VkDisplaySurfaceCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkDisplaySurfaceCreateFlagsKHR flags;
VkDisplayModeKHR displayMode;
uint32_t planeIndex;
uint32_t planeStackIndex;
VkSurfaceTransformFlagBitsKHR transform;
float globalAlpha;
VkDisplayPlaneAlphaFlagBitsKHR alphaMode;
VkExtent2D imageExtent;
} VkDisplaySurfaceCreateInfoKHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
flags保留供将来使用,并且必须为零。 -
displayMode是一个 VkDisplayModeKHR 句柄,指定显示此表面时要使用的模式。 -
planeIndex是此表面出现的平面。 -
planeStackIndex是平面的 Z 顺序。 -
transform是一个 VkSurfaceTransformFlagBitsKHR 值,指定要作为扫描输出操作的一部分应用于图像的转换。 -
globalAlpha是全局 alpha 值。如果alphaMode不是VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR,则忽略此值。 -
alphaMode是一个 VkDisplayPlaneAlphaFlagBitsKHR 值,指定要使用的 alpha 混合类型。 -
imageExtent是用于表面的可呈现图像的大小。
|
创建显示表面不得修改其命名的显示器、平面或其他资源的状态。例如,它不得应用指定的模式来设置在关联的显示器上。显示配置的应用作为呈现到显示表面的副作用发生。 |
// Provided by VK_KHR_display
typedef VkFlags VkDisplaySurfaceCreateFlagsKHR;
VkDisplaySurfaceCreateFlagsKHR 是一个用于设置掩码的位掩码类型,但目前保留供将来使用。
可以在 VkDisplaySurfaceCreateInfoKHR::alphaMode 中设置的位,用于指定在显示器上使用的 alpha 混合类型,包括:
// Provided by VK_KHR_display
typedef enum VkDisplayPlaneAlphaFlagBitsKHR {
VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR = 0x00000001,
VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR = 0x00000002,
VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR = 0x00000004,
VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR = 0x00000008,
} VkDisplayPlaneAlphaFlagBitsKHR;
-
VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR指定源图像将被视为不透明。 -
VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR指定必须指定一个全局 alpha 值,该值将应用于源图像中的所有像素。 -
VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR指定 alpha 值将由源图像像素的 alpha 分量确定。如果源格式不包含 alpha 值,则不会应用混合。源 alpha 值不会预乘到源图像的其他颜色分量中。 -
VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR等同于VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR,只是源 alpha 值被假定为已预乘到源图像的其他颜色分量中。
// Provided by VK_KHR_display
typedef VkFlags VkDisplayPlaneAlphaFlagsKHR;
VkDisplayPlaneAlphaFlagsKHR 是一个位掩码类型,用于设置零个或多个 VkDisplayPlaneAlphaFlagBitsKHR 的掩码。
VkDisplaySurfaceStereoCreateInfoNV 结构定义如下:
// Provided by VK_NV_display_stereo
typedef struct VkDisplaySurfaceStereoCreateInfoNV {
VkStructureType sType;
const void* pNext;
VkDisplaySurfaceStereoTypeNV stereoType;
} VkDisplaySurfaceStereoCreateInfoNV;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
stereoType是一个 VkDisplaySurfaceStereoTypeNV 值,指定显示器将配置的 3D 立体呈现类型。
VkDisplaySurfaceStereoCreateInfoNV::stereoType 的可能值,指定显示器将配置的 3D 立体呈现类型,包括:
// Provided by VK_NV_display_stereo
typedef enum VkDisplaySurfaceStereoTypeNV {
VK_DISPLAY_SURFACE_STEREO_TYPE_NONE_NV = 0,
VK_DISPLAY_SURFACE_STEREO_TYPE_ONBOARD_DIN_NV = 1,
VK_DISPLAY_SURFACE_STEREO_TYPE_HDMI_3D_NV = 2,
VK_DISPLAY_SURFACE_STEREO_TYPE_INBAND_DISPLAYPORT_NV = 3,
} VkDisplaySurfaceStereoTypeNV;
-
VK_DISPLAY_SURFACE_STEREO_TYPE_NONE_NV指定不配置立体呈现。如果没有提供 VkDisplaySurfaceStereoCreateInfoNV,这是默认行为。 -
VK_DISPLAY_SURFACE_STEREO_TYPE_ONBOARD_DIN_NV指定用于通过图形卡背面的 DIN 连接器连接的眼镜的配置。 -
VK_DISPLAY_SURFACE_STEREO_TYPE_HDMI_3D_NV指定用于具有自己立体发射器的 HDMI 3D 兼容显示设备的配置。这也称为 HDMI 帧封装立体,其中左右眼图像堆叠成一个具有双倍像素时钟和刷新率的单个帧。 -
VK_DISPLAY_SURFACE_STEREO_TYPE_INBAND_DISPLAYPORT_NV指定用于具有带内立体信号和发射器的 DisplayPort 显示设备的配置。
呈现到无头表面
Vulkan 渲染可以呈现到无头表面,其中呈现操作是一个无操作,不会产生外部可见的结果。
|
由于没有真正的呈现目标,因此可以扩展无头呈现引擎以施加任意或可自定义的一组限制和功能。这使其成为针对各种呈现引擎的应用程序的有用可移植测试目标,而实际目标呈现引擎可能稀缺、不可用或出于通用 Vulkan 应用程序开发的考虑而不希望或不方便使用。 必须使用通常的表面查询机制来确定实现的实际限制和功能。 |
要创建无头 VkSurfaceKHR 对象,请调用
// Provided by VK_EXT_headless_surface
VkResult vkCreateHeadlessSurfaceEXT(
VkInstance instance,
const VkHeadlessSurfaceCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
-
instance是与 surface 关联的实例。 -
pCreateInfo是指向 VkHeadlessSurfaceCreateInfoEXT 结构的指针,该结构包含影响表面对象创建的参数。 -
pAllocator是当没有更具体的分配器可用时(请参阅 内存分配)用于为 surface 对象分配主机内存的分配器。 -
pSurface是一个指向VkSurfaceKHR句柄的指针,创建的 surface 对象将返回到该句柄中。
VkHeadlessSurfaceCreateInfoEXT 结构定义如下:
// Provided by VK_EXT_headless_surface
typedef struct VkHeadlessSurfaceCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkHeadlessSurfaceCreateFlagsEXT flags;
} VkHeadlessSurfaceCreateInfoEXT;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
flags保留供将来使用。
对于无头表面,currentExtent 是保留值 (0xFFFFFFFF, 0xFFFFFFFF)。无论应用程序将交换链的 imageExtent 设置为多大,在第一个图像呈现后,表面大小都将为该值。
// Provided by VK_EXT_headless_surface
typedef VkFlags VkHeadlessSurfaceCreateFlagsEXT;
VkHeadlessSurfaceCreateFlagsEXT 是用于设置掩码的位掩码类型,但目前保留供将来使用。
查询 WSI 支持
并非所有物理设备都包含 WSI 支持。在物理设备中,并非所有队列族都支持呈现。WSI 支持和兼容性可以以平台无关的方式确定(这决定了对特定表面对象的呈现支持),并且可以以平台特定的方式确定(这决定了在指定物理设备上的呈现支持,但不保证对特定表面对象的呈现支持)。
要确定物理设备的队列族是否支持呈现到给定表面,请调用
// Provided by VK_KHR_surface
VkResult vkGetPhysicalDeviceSurfaceSupportKHR(
VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
VkSurfaceKHR surface,
VkBool32* pSupported);
-
physicalDevice是物理设备。 -
queueFamilyIndex是队列族。 -
surface是表面。 -
pSupported是指向VkBool32的指针。VK_TRUE表示支持,而VK_FALSE表示不支持。
Wayland 平台
要确定物理设备的队列族是否支持呈现到 Wayland 合成器,请调用
// Provided by VK_KHR_wayland_surface
VkBool32 vkGetPhysicalDeviceWaylandPresentationSupportKHR(
VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
struct wl_display* display);
-
physicalDevice是物理设备。 -
queueFamilyIndex是队列族索引。 -
display是指向与 Wayland 合成器关联的wl_display的指针。
可以在创建表面之前调用此平台特定函数。
Win32 平台
要确定物理设备的队列族是否支持呈现到 Microsoft Windows 桌面,请调用
// Provided by VK_KHR_win32_surface
VkBool32 vkGetPhysicalDeviceWin32PresentationSupportKHR(
VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex);
-
physicalDevice是物理设备。 -
queueFamilyIndex是队列族索引。
可以在创建表面之前调用此平台特定函数。
XCB 平台
要确定物理设备的队列族是否支持使用 XCB 客户端库呈现到 X11 服务器,请调用
// Provided by VK_KHR_xcb_surface
VkBool32 vkGetPhysicalDeviceXcbPresentationSupportKHR(
VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
xcb_connection_t* connection,
xcb_visualid_t visual_id);
-
physicalDevice是物理设备。 -
queueFamilyIndex是队列族索引。 -
connection是指向 X 服务器的xcb_connection_t的指针。 -
visual_id是 X11 可视化 (xcb_visualid_t)。
可以在创建表面之前调用此平台特定函数。
Xlib 平台
要确定物理设备的队列族是否支持使用 Xlib 客户端库呈现到 X11 服务器,请调用
// Provided by VK_KHR_xlib_surface
VkBool32 vkGetPhysicalDeviceXlibPresentationSupportKHR(
VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
Display* dpy,
VisualID visualID);
-
physicalDevice是物理设备。 -
queueFamilyIndex是队列族索引。 -
dpy是指向服务器的 XlibDisplay连接的指针。 -
visualId是 X11 可视化 (VisualID)。
可以在创建表面之前调用此平台特定函数。
DirectFB 平台
要确定物理设备的队列族是否支持使用 DirectFB 库进行呈现,请调用
// Provided by VK_EXT_directfb_surface
VkBool32 vkGetPhysicalDeviceDirectFBPresentationSupportEXT(
VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
IDirectFB* dfb);
-
physicalDevice是物理设备。 -
queueFamilyIndex是队列族索引。 -
dfb是指向 DirectFB 的IDirectFB主接口的指针。
可以在创建表面之前调用此平台特定函数。
Google Games 平台
在 Google Games 平台上,具有 VK_QUEUE_GRAPHICS_BIT 或 VK_QUEUE_COMPUTE_BIT 功能的所有物理设备和队列族必须能够使用任何 Google Games Platform 流描述符进行呈现。因此,没有针对 Google Games 平台特定功能的查询。
QNX Screen 平台
要确定物理设备的队列族是否支持呈现到 QNX Screen 合成器,请调用
// Provided by VK_QNX_screen_surface
VkBool32 vkGetPhysicalDeviceScreenPresentationSupportQNX(
VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
struct _screen_window* window);
-
physicalDevice是物理设备。 -
queueFamilyIndex是队列族索引。 -
window是 QNX Screenwindow对象。
可以在创建表面之前调用此平台特定函数。
表面查询
以表面为目标的交换链的功能是 WSI 平台、原生窗口或显示以及物理设备的功能的交集。可以使用本节中列出的查询获得生成的功能。
|
除了通过以下表面查询获得的表面功能外,交换链图像还受 vkGetPhysicalDeviceImageFormatProperties 报告的普通图像创建限制的约束。正如应用程序在适当的有效使用部分中所指示的那样,在创建交换链图像时,必须满足表面功能和图像创建限制。 |
表面功能
要查询表面的基本功能(创建交换链所需的),请调用
// Provided by VK_KHR_surface
VkResult vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
VkPhysicalDevice physicalDevice,
VkSurfaceKHR surface,
VkSurfaceCapabilitiesKHR* pSurfaceCapabilities);
-
physicalDevice是将与要创建的交换链关联的物理设备,如 vkCreateSwapchainKHR 所述。 -
surface是将与交换链关联的表面。 -
pSurfaceCapabilities是指向 VkSurfaceCapabilitiesKHR 结构的指针,该结构将返回功能。
VkSurfaceCapabilitiesKHR 结构的定义如下
// Provided by VK_KHR_surface
typedef struct VkSurfaceCapabilitiesKHR {
uint32_t minImageCount;
uint32_t maxImageCount;
VkExtent2D currentExtent;
VkExtent2D minImageExtent;
VkExtent2D maxImageExtent;
uint32_t maxImageArrayLayers;
VkSurfaceTransformFlagsKHR supportedTransforms;
VkSurfaceTransformFlagBitsKHR currentTransform;
VkCompositeAlphaFlagsKHR supportedCompositeAlpha;
VkImageUsageFlags supportedUsageFlags;
} VkSurfaceCapabilitiesKHR;
-
minImageCount是指定设备为该表面创建的交换链支持的最小图像数量,并且至少为 1。 -
maxImageCount是指定设备为该表面创建的交换链支持的最大图像数量,并且将为 0,或者大于或等于minImageCount。值为 0 表示图像数量没有限制,但可能存在与可呈现图像使用的总内存量相关的限制。 -
currentExtent是表面的当前宽度和高度,或者是特殊值 (0xFFFFFFFF, 0xFFFFFFFF),指示表面大小将由以该表面为目标的交换链的范围确定。 -
minImageExtent包含指定设备上表面的最小有效交换链范围。范围的width和height将分别小于或等于currentExtent的相应width和height,除非currentExtent具有上述特殊值。 -
maxImageExtent包含指定设备上表面的最大有效交换链范围。范围的width和height将分别大于或等于minImageExtent的相应width和height。范围的width和height将分别大于或等于currentExtent的相应width和height,除非currentExtent具有上述特殊值。 -
maxImageArrayLayers是为该设备和表面创建的交换链中可呈现图像可以具有的最大层数,并且至少为 1。 -
supportedTransforms是 VkSurfaceTransformFlagBitsKHR 的位掩码,指示指定设备上表面支持的呈现变换。至少会设置一位。 -
currentTransform是 VkSurfaceTransformFlagBitsKHR 值,指示表面相对于呈现引擎自然方向的当前变换。 -
supportedCompositeAlpha是一个 VkCompositeAlphaFlagBitsKHR 的位掩码,表示指定设备上该表面演示引擎支持的 alpha 混合模式,并且至少设置一位。通过使用没有 alpha 分量的图像格式,或者通过确保可呈现图像中的所有像素的 alpha 值为 1.0,**可以**在任何 alpha 混合模式中实现不透明合成。 -
supportedUsageFlags是一个 VkImageUsageFlagBits 的位掩码,表示应用程序**可以**使用通过将 VkPresentModeKHR 设置为VK_PRESENT_MODE_FIFO_LATEST_READY_EXT、VK_PRESENT_MODE_IMMEDIATE_KHR、VK_PRESENT_MODE_MAILBOX_KHR、VK_PRESENT_MODE_FIFO_KHR或VK_PRESENT_MODE_FIFO_RELAXED_KHR创建的交换链的可呈现图像的方式。集合中**必须**包含VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT。实现**可能**支持其他用法。
|
当使用 |
|
诸如 min(N, |
要查询核心或扩展定义的表面的基本功能,请调用
// Provided by VK_KHR_get_surface_capabilities2
VkResult vkGetPhysicalDeviceSurfaceCapabilities2KHR(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
VkSurfaceCapabilities2KHR* pSurfaceCapabilities);
-
physicalDevice是将与要创建的交换链关联的物理设备,如 vkCreateSwapchainKHR 所述。 -
pSurfaceInfo是指向 VkPhysicalDeviceSurfaceInfo2KHR 结构的指针,该结构描述了表面和其他将被 vkCreateSwapchainKHR 消耗的固定参数。 -
pSurfaceCapabilities是指向 VkSurfaceCapabilities2KHR 结构的指针,该结构中返回功能。
vkGetPhysicalDeviceSurfaceCapabilities2KHR 的行为类似于 vkGetPhysicalDeviceSurfaceCapabilitiesKHR,它可以通过链接的输入结构指定扩展输入,并通过链接的输出结构返回扩展信息。
VkPhysicalDeviceSurfaceInfo2KHR 结构定义为
// Provided by VK_KHR_get_surface_capabilities2
typedef struct VkPhysicalDeviceSurfaceInfo2KHR {
VkStructureType sType;
const void* pNext;
VkSurfaceKHR surface;
} VkPhysicalDeviceSurfaceInfo2KHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
surface是将与交换链关联的表面。
VkPhysicalDeviceSurfaceInfo2KHR 的成员对应于 vkGetPhysicalDeviceSurfaceCapabilitiesKHR 的参数,并添加了 sType 和 pNext 以实现可扩展性。
使用不同的全屏独占设置创建的交换链**可能**可以使用表面的其他功能 - 特别是当独占全屏访问由应用程序控制时。可以通过在此结构用于查询表面属性时,将 VkSurfaceFullScreenExclusiveInfoEXT 结构添加到其 pNext 链来查询这些其他功能。此外,对于具有应用程序控制的独占全屏访问的 Win32 表面,链接 VkSurfaceFullScreenExclusiveWin32InfoEXT 结构**可能**还会报告其他表面功能。这些其他功能仅适用于使用 VkSwapchainCreateInfoKHR 的 pNext 链中包含的相同参数创建的交换链。
如果 VkSwapchainCreateInfoKHR 的 pNext 链包含 VkSurfaceFullScreenExclusiveInfoEXT 结构,则该结构指定应用程序首选的全屏切换行为。
VkSurfaceFullScreenExclusiveInfoEXT 结构定义如下:
// Provided by VK_EXT_full_screen_exclusive
typedef struct VkSurfaceFullScreenExclusiveInfoEXT {
VkStructureType sType;
void* pNext;
VkFullScreenExclusiveEXT fullScreenExclusive;
} VkSurfaceFullScreenExclusiveInfoEXT;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
fullScreenExclusive是一个 VkFullScreenExclusiveEXT 值,指定首选的全屏切换行为。
如果此结构不存在,则认为 fullScreenExclusive 为 VK_FULL_SCREEN_EXCLUSIVE_DEFAULT_EXT。
VkSurfaceFullScreenExclusiveInfoEXT::fullScreenExclusive 的可能值包括:
// Provided by VK_EXT_full_screen_exclusive
typedef enum VkFullScreenExclusiveEXT {
VK_FULL_SCREEN_EXCLUSIVE_DEFAULT_EXT = 0,
VK_FULL_SCREEN_EXCLUSIVE_ALLOWED_EXT = 1,
VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT = 2,
VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT = 3,
} VkFullScreenExclusiveEXT;
-
VK_FULL_SCREEN_EXCLUSIVE_DEFAULT_EXT指定实现**应该**通过其认为合适的任何方式确定适当的全屏方法。 -
VK_FULL_SCREEN_EXCLUSIVE_ALLOWED_EXT指定实现**可以**在可用时使用全屏独占机制。此类机制**可能**导致更好的性能和/或不同的呈现能力,但**可能**需要在交换链初始化、首次呈现和/或销毁期间进行更具破坏性的转换。 -
VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT指定实现**应该**避免使用依赖于破坏性转换的全屏机制。 -
VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT指定应用程序将通过使用 vkAcquireFullScreenExclusiveModeEXT 和 vkReleaseFullScreenExclusiveModeEXT 命令来管理全屏独占模式。
VkSurfaceFullScreenExclusiveWin32InfoEXT 结构定义如下:
// Provided by VK_KHR_win32_surface with VK_EXT_full_screen_exclusive
typedef struct VkSurfaceFullScreenExclusiveWin32InfoEXT {
VkStructureType sType;
const void* pNext;
HMONITOR hmonitor;
} VkSurfaceFullScreenExclusiveWin32InfoEXT;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
hmonitor是 Win32HMONITOR句柄,用于标识要创建表面的显示器。
|
如果在使用此结构创建的交换链的生命周期中 |
|
应用程序有责任使用适当的平台 API 更改目标 Win32 显示器的显示设置。此类更改**可能**会改变为创建的表面报告的表面功能。 |
VkSurfaceCapabilities2KHR 结构定义如下:
// Provided by VK_KHR_get_surface_capabilities2
typedef struct VkSurfaceCapabilities2KHR {
VkStructureType sType;
void* pNext;
VkSurfaceCapabilitiesKHR surfaceCapabilities;
} VkSurfaceCapabilities2KHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
surfaceCapabilities是一个 VkSurfaceCapabilitiesKHR 结构,描述指定表面的功能。
如果启用了 VK_GOOGLE_surfaceless_query 扩展,并且 vkGetPhysicalDeviceSurfaceCapabilities2KHR 调用中的 VkPhysicalDeviceSurfaceInfo2KHR::surface 为 VK_NULL_HANDLE,则 minImageCount、maxImageCount、currentExtent 和 currentTransform 中返回的值不会反映任何表面的值,而是如下所示:
-
minImageCount和maxImageCount将为 0xFFFFFFFF -
currentExtent将为 (0xFFFFFFFF, 0xFFFFFFFF) -
currentTransform将为VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR
应用程序使用 VkSurfaceProtectedCapabilitiesKHR 查询受保护的 VkSurfaceKHR 是否可在特定窗口系统上显示,该结构**可以**在 VkSurfaceCapabilities2KHR 的 pNext 参数中传递。
VkSurfaceProtectedCapabilitiesKHR 结构定义如下:
// Provided by VK_KHR_surface_protected_capabilities
typedef struct VkSurfaceProtectedCapabilitiesKHR {
VkStructureType sType;
const void* pNext;
VkBool32 supportsProtected;
} VkSurfaceProtectedCapabilitiesKHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
supportsProtected指定是否可以屏幕上显示从 VkPhysicalDeviceSurfaceInfo2KHR::surface为特定窗口系统创建的受保护交换链。如果supportsProtected为VK_TRUE,则**必须**支持为surface设置了VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR标志的交换链的创建。
如果启用了 VK_GOOGLE_surfaceless_query 扩展,则在 supportsProtected 中返回的值对于在此物理设备上创建的每个有效表面都相同,因此在 vkGetPhysicalDeviceSurfaceCapabilities2KHR 调用中,VkPhysicalDeviceSurfaceInfo2KHR::surface **可以**为 VK_NULL_HANDLE。 在这种情况下,VkSurfaceCapabilities2KHR::surfaceCapabilities 的内容以及链接到它的任何其他结构的内容将是未定义的。
VkSurfacePresentScalingCapabilitiesEXT 结构定义如下:
// Provided by VK_EXT_surface_maintenance1
typedef struct VkSurfacePresentScalingCapabilitiesEXT {
VkStructureType sType;
void* pNext;
VkPresentScalingFlagsEXT supportedPresentScaling;
VkPresentGravityFlagsEXT supportedPresentGravityX;
VkPresentGravityFlagsEXT supportedPresentGravityY;
VkExtent2D minScaledImageExtent;
VkExtent2D maxScaledImageExtent;
} VkSurfacePresentScalingCapabilitiesEXT;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
supportedPresentScaling是一个 VkPresentScalingFlagBitsEXT 的位掩码,表示表面支持的缩放方法,如果不支持应用程序定义的缩放,则为0。 -
supportedPresentGravityX是一个 VkPresentGravityFlagBitsEXT 的位掩码,表示表面支持的 X 轴像素重力,如果 X 轴不支持 Vulkan 定义的像素重力,则为0。 -
supportedPresentGravityY是一个 VkPresentGravityFlagBitsEXT 的位掩码,表示表面支持的 Y 轴像素重力,如果 Y 轴不支持 Vulkan 定义的像素重力,则为0。 -
minScaledImageExtent包含当使用supportedPresentScaling中指定的缩放方法之一时,表面在指定设备上的最小有效交换链范围,或者特殊值 (0xFFFFFFFF, 0xFFFFFFFF),表示表面大小将由以该表面为目标的交换链的范围确定。范围的width和height将各自小于或等于 VkSurfaceCapabilitiesKHR::minImageExtent的对应width和height。 -
maxScaledImageExtent包含当使用supportedPresentScaling中指定的缩放方法之一时,表面在指定设备上的最大有效交换链范围,或者与minScaledImageExtent描述的特殊值相同。范围的width和height将各自大于或等于 VkSurfaceCapabilitiesKHR::maxImageExtent的对应width和height。
在创建其缩放模式可以通过使用 VkSwapchainPresentScalingCreateInfoEXT 指定的交换链之前,通过在调用 vkGetPhysicalDeviceSurfaceCapabilities2KHR 时,将 VkSurfacePresentModeEXT 结构体包含在 VkPhysicalDeviceSurfaceInfo2KHR 的 pNext 链中,来获取支持的缩放模式集合。对于通过 VkSurfacePresentModeCompatibilityEXT 获取的任何兼容的呈现模式,实现必须在 VkSurfacePresentScalingCapabilitiesEXT 中返回相同的值。
在 VkSurfacePresentScalingCapabilitiesEXT::supportedPresentScaling 中可以设置的位,指定表面支持的缩放模式,有
// Provided by VK_EXT_surface_maintenance1
typedef enum VkPresentScalingFlagBitsEXT {
VK_PRESENT_SCALING_ONE_TO_ONE_BIT_EXT = 0x00000001,
VK_PRESENT_SCALING_ASPECT_RATIO_STRETCH_BIT_EXT = 0x00000002,
VK_PRESENT_SCALING_STRETCH_BIT_EXT = 0x00000004,
} VkPresentScalingFlagBitsEXT;
-
VK_PRESENT_SCALING_ONE_TO_ONE_BIT_EXT指定不进行缩放,并且交换链图像中的像素被映射到表面中的一个且仅一个像素。像素之间的映射由选择的呈现重力定义。 -
VK_PRESENT_SCALING_ASPECT_RATIO_STRETCH_BIT_EXT指定将缩小或放大交换链图像,使得至少一个结果宽度或高度等于相应的表面尺寸,并且另一个结果尺寸小于或等于相应的表面尺寸,并且结果图像的纵横比与原始交换链图像的纵横比相同。 -
VK_PRESENT_SCALING_STRETCH_BIT_EXT指定将缩小或放大交换链图像,使得结果图像尺寸等于表面的尺寸。
// Provided by VK_EXT_surface_maintenance1
typedef VkFlags VkPresentScalingFlagsEXT;
VkPresentScalingFlagsEXT 是一种位掩码类型,用于设置零个或多个 VkPresentScalingFlagBitsEXT 的掩码。
在 VkSurfacePresentScalingCapabilitiesEXT::supportedPresentGravityX 或 supportedPresentGravityY 字段中可以设置的位,指定表面支持的呈现像素的重力,有
// Provided by VK_EXT_surface_maintenance1
typedef enum VkPresentGravityFlagBitsEXT {
VK_PRESENT_GRAVITY_MIN_BIT_EXT = 0x00000001,
VK_PRESENT_GRAVITY_MAX_BIT_EXT = 0x00000002,
VK_PRESENT_GRAVITY_CENTERED_BIT_EXT = 0x00000004,
} VkPresentGravityFlagBitsEXT;
-
VK_PRESENT_GRAVITY_MIN_BIT_EXT表示像素将朝向表面的顶部或左侧移动。 -
VK_PRESENT_GRAVITY_MAX_BIT_EXT表示像素将朝向表面的底部或右侧移动。 -
VK_PRESENT_GRAVITY_CENTERED_BIT_EXT表示像素将在表面中居中。
如果 VkSurfaceCapabilitiesKHR::currentTransform 中的值不是 VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,则重力配置是应用于转换之前还是之后的呈现图像由实现定义。
// Provided by VK_EXT_surface_maintenance1
typedef VkFlags VkPresentGravityFlagsEXT;
VkPresentGravityFlagsEXT 是一种位掩码类型,用于设置零个或多个 VkPresentGravityFlagBitsEXT 的掩码。
VkSurfacePresentModeEXT 结构定义如下
// Provided by VK_EXT_surface_maintenance1
typedef struct VkSurfacePresentModeEXT {
VkStructureType sType;
void* pNext;
VkPresentModeKHR presentMode;
} VkSurfacePresentModeEXT;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
presentMode是交换链将使用的呈现模式。
如果 VkSurfacePresentModeEXT 结构包含在 VkPhysicalDeviceSurfaceInfo2KHR 的 pNext 链中,则 VkSurfaceCapabilitiesKHR::minImageCount、VkSurfaceCapabilitiesKHR::maxImageCount、VkSurfacePresentScalingCapabilitiesEXT::minScaledImageExtent 和 VkSurfacePresentScalingCapabilitiesEXT::maxScaledImageExtent 中返回的值仅对指定的 presentMode 有效。如果 presentMode 为 VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR 或 VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR,则每个呈现模式的图像计数必须都为一。每个呈现模式的图像计数可能小于或大于未提供 VkSurfacePresentModeEXT 时返回的图像计数。
|
如果为交换链创建提供了 VkSwapchainPresentModesCreateInfoEXT,则对向前进度的要求可能不那么严格。例如,FIFO 交换链可能只需要 2 个图像来保证向前进度,但 MAILBOX 交换链可能需要 4 个。如果没有每个呈现的图像计数,这样的实现必须在 VkSurfaceCapabilitiesKHR:: 为了规范与不了解或不使用此功能的应用程序向后兼容,需要 VkSwapchainPresentModesCreateInfoEXT。 |
VkSurfacePresentModeCompatibilityEXT 结构定义如下
// Provided by VK_EXT_surface_maintenance1
typedef struct VkSurfacePresentModeCompatibilityEXT {
VkStructureType sType;
void* pNext;
uint32_t presentModeCount;
VkPresentModeKHR* pPresentModes;
} VkSurfacePresentModeCompatibilityEXT;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
presentModeCount是与可用或查询的呈现模式数量相关的整数,如下所述。 -
pPresentModes是指向 VkPresentModeKHR 数组的指针,其中返回与给定呈现模式兼容的呈现模式。
如果 pPresentModes 为 NULL,则与 VkSurfacePresentModeEXT 中指定的模式兼容的显示模式数量将返回到 presentModeCount 中。否则,presentModeCount 必须 指向一个由应用程序设置的变量,该变量表示 pPresentModes 数组中的元素数量,并且在返回时,该变量将被实际写入 pPresentModes 的值的数量覆盖。如果 presentModeCount 的值小于支持的兼容显示模式的数量,则最多会将 presentModeCount 个值写入 pPresentModes。除非 presentModeCount 为零,否则实现 必须 在 pPresentModes 中包含传递给 VkSurfacePresentModeEXT 的显示模式。
在创建可以通过使用 VkSwapchainPresentModesCreateInfoEXT 修改其显示模式的交换链之前,通过在调用 vkGetPhysicalDeviceSurfaceCapabilities2KHR 时,在 VkPhysicalDeviceSurfaceInfo2KHR 的 pNext 链中包含 VkSurfacePresentModeEXT 结构,来获取与给定初始显示模式兼容的显示模式集合。
VkSharedPresentSurfaceCapabilitiesKHR 结构定义如下
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
sharedPresentSupportedUsageFlags是一个 VkImageUsageFlagBits 的位掩码,表示应用程序 可以 如何使用由交换链创建的可共享显示图像,该交换链的 VkPresentModeKHR 设置为VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR或VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR以用于指定设备上的表面。VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT必须 包含在该集合中,但实现 可能 支持其他用法。
VkDisplayNativeHdrSurfaceCapabilitiesAMD 结构定义如下
// Provided by VK_AMD_display_native_hdr
typedef struct VkDisplayNativeHdrSurfaceCapabilitiesAMD {
VkStructureType sType;
void* pNext;
VkBool32 localDimmingSupport;
} VkDisplayNativeHdrSurfaceCapabilitiesAMD;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
localDimmingSupport指定表面是否支持局部调光。如果为VK_TRUE,则可以使用 VkSwapchainDisplayNativeHdrCreateInfoAMD 显式启用或禁用表面的局部调光。局部调光也可以在交换链的生命周期内被 vkSetLocalDimmingAMD 覆盖。
VkSurfaceCapabilitiesFullScreenExclusiveEXT 结构定义如下
// Provided by VK_EXT_full_screen_exclusive
typedef struct VkSurfaceCapabilitiesFullScreenExclusiveEXT {
VkStructureType sType;
void* pNext;
VkBool32 fullScreenExclusiveSupported;
} VkSurfaceCapabilitiesFullScreenExclusiveEXT;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
fullScreenExclusiveControlSupported是一个布尔值,描述表面是否能够使用独占全屏访问。
此结构 可以 包含在 VkSurfaceCapabilities2KHR 的 pNext 链中,以确定对独占全屏访问的支持。如果 fullScreenExclusiveSupported 为 VK_FALSE,则表示此表面无法获得独占全屏访问。
如果 fullScreenExclusiveSupported 为 VK_FALSE,则应用程序 必须 不尝试创建设置了 VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT 的交换链。
VkSurfaceCapabilitiesPresentBarrierNV 结构定义如下
// Provided by VK_NV_present_barrier
typedef struct VkSurfaceCapabilitiesPresentBarrierNV {
VkStructureType sType;
void* pNext;
VkBool32 presentBarrierSupported;
} VkSurfaceCapabilitiesPresentBarrierNV;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
presentBarrierSupported是一个布尔值,描述表面是否能够使用显示屏障功能。
此结构 可以 包含在 VkSurfaceCapabilities2KHR 的 pNext 链中,以确定对显示屏障访问的支持。如果 presentBarrierSupported 为 VK_FALSE,则表示此表面无法获得显示屏障功能。
要查询表面的基本功能(创建交换链所需的),请调用
// Provided by VK_EXT_display_surface_counter
VkResult vkGetPhysicalDeviceSurfaceCapabilities2EXT(
VkPhysicalDevice physicalDevice,
VkSurfaceKHR surface,
VkSurfaceCapabilities2EXT* pSurfaceCapabilities);
-
physicalDevice是将与要创建的交换链关联的物理设备,如 vkCreateSwapchainKHR 所述。 -
surface是将与交换链关联的表面。 -
pSurfaceCapabilities是指向 VkSurfaceCapabilities2EXT 结构的指针,其中返回了功能。
vkGetPhysicalDeviceSurfaceCapabilities2EXT 的行为类似于 vkGetPhysicalDeviceSurfaceCapabilitiesKHR,它可以通过将扩展结构添加到其 pSurfaceCapabilities 参数的 pNext 链来返回扩展信息。
VkSurfaceCapabilities2EXT 结构定义如下
// Provided by VK_EXT_display_surface_counter
typedef struct VkSurfaceCapabilities2EXT {
VkStructureType sType;
void* pNext;
uint32_t minImageCount;
uint32_t maxImageCount;
VkExtent2D currentExtent;
VkExtent2D minImageExtent;
VkExtent2D maxImageExtent;
uint32_t maxImageArrayLayers;
VkSurfaceTransformFlagsKHR supportedTransforms;
VkSurfaceTransformFlagBitsKHR currentTransform;
VkCompositeAlphaFlagsKHR supportedCompositeAlpha;
VkImageUsageFlags supportedUsageFlags;
VkSurfaceCounterFlagsEXT supportedSurfaceCounters;
} VkSurfaceCapabilities2EXT;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
minImageCount是指定设备为该表面创建的交换链支持的最小图像数量,并且至少为 1。 -
maxImageCount是指定设备为该表面创建的交换链支持的最大图像数量,并且将为 0,或者大于或等于minImageCount。值为 0 表示图像数量没有限制,但可能存在与可呈现图像使用的总内存量相关的限制。 -
currentExtent是表面的当前宽度和高度,或者是特殊值 (0xFFFFFFFF, 0xFFFFFFFF),指示表面大小将由以该表面为目标的交换链的范围确定。 -
minImageExtent包含指定设备上表面的最小有效交换链范围。范围的width和height将分别小于或等于currentExtent的相应width和height,除非currentExtent具有上述特殊值。 -
maxImageExtent包含指定设备上表面的最大有效交换链范围。范围的width和height将分别大于或等于minImageExtent的相应width和height。范围的width和height将分别大于或等于currentExtent的相应width和height,除非currentExtent具有上述特殊值。 -
maxImageArrayLayers是为该设备和表面创建的交换链中可呈现图像可以具有的最大层数,并且至少为 1。 -
supportedTransforms是 VkSurfaceTransformFlagBitsKHR 的位掩码,指示指定设备上表面支持的呈现变换。至少会设置一位。 -
currentTransform是 VkSurfaceTransformFlagBitsKHR 值,指示表面相对于呈现引擎自然方向的当前变换。 -
supportedCompositeAlpha是一个 VkCompositeAlphaFlagBitsKHR 的位掩码,表示指定设备上该表面演示引擎支持的 alpha 混合模式,并且至少设置一位。通过使用没有 alpha 分量的图像格式,或者通过确保可呈现图像中的所有像素的 alpha 值为 1.0,**可以**在任何 alpha 混合模式中实现不透明合成。 -
supportedUsageFlags是一个 VkImageUsageFlagBits 的位掩码,表示应用程序**可以**使用通过将 VkPresentModeKHR 设置为VK_PRESENT_MODE_FIFO_LATEST_READY_EXT、VK_PRESENT_MODE_IMMEDIATE_KHR、VK_PRESENT_MODE_MAILBOX_KHR、VK_PRESENT_MODE_FIFO_KHR或VK_PRESENT_MODE_FIFO_RELAXED_KHR创建的交换链的可呈现图像的方式。集合中**必须**包含VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT。实现**可能**支持其他用法。 -
supportedSurfaceCounters是一个 VkSurfaceCounterFlagBitsEXT 的位掩码,指示支持的表面计数器类型。
在 VkSurfaceCapabilities2EXT::supportedSurfaceCounters 中 可以 设置的位,指示支持的表面计数器类型,有
// Provided by VK_EXT_display_surface_counter
typedef enum VkSurfaceCounterFlagBitsEXT {
VK_SURFACE_COUNTER_VBLANK_BIT_EXT = 0x00000001,
// VK_SURFACE_COUNTER_VBLANK_EXT is a deprecated alias
VK_SURFACE_COUNTER_VBLANK_EXT = VK_SURFACE_COUNTER_VBLANK_BIT_EXT,
} VkSurfaceCounterFlagBitsEXT;
-
VK_SURFACE_COUNTER_VBLANK_BIT_EXT指定一个计数器,该计数器在与表面关联的显示器上每次发生垂直消隐周期时递增一次。
// Provided by VK_EXT_display_surface_counter
typedef VkFlags VkSurfaceCounterFlagsEXT;
VkSurfaceCounterFlagsEXT 是一个位掩码类型,用于设置零个或多个 VkSurfaceCounterFlagBitsEXT 的掩码。
在 VkSurfaceCapabilitiesKHR::supportedTransforms 中可能设置的位,指示指定设备上表面支持的演示转换,以及 VkSurfaceCapabilitiesKHR::currentTransform 的可能值,指示表面相对于演示引擎自然方向的当前转换,如下所示:
// Provided by VK_KHR_surface
typedef enum VkSurfaceTransformFlagBitsKHR {
VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR = 0x00000001,
VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR = 0x00000002,
VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR = 0x00000004,
VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR = 0x00000008,
VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR = 0x00000010,
VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR = 0x00000020,
VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR = 0x00000040,
VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR = 0x00000080,
VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 0x00000100,
} VkSurfaceTransformFlagBitsKHR;
-
VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR指定图像内容在呈现时没有经过任何转换。 -
VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR指定图像内容顺时针旋转 90 度。 -
VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR指定图像内容顺时针旋转 180 度。 -
VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR指定图像内容顺时针旋转 270 度。 -
VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR指定图像内容水平镜像。 -
VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR指定图像内容先水平镜像,然后顺时针旋转 90 度。 -
VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR指定图像内容先水平镜像,然后顺时针旋转 180 度。 -
VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR指定图像内容先水平镜像,然后顺时针旋转 270 度。 -
VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR指定演示转换未指定,而是由 Vulkan 之外的平台特定考虑因素和机制确定。
// Provided by VK_KHR_display
typedef VkFlags VkSurfaceTransformFlagsKHR;
VkSurfaceTransformFlagsKHR 是一种位掩码类型,用于设置零个或多个 VkSurfaceTransformFlagBitsKHR 的掩码。
supportedCompositeAlpha 成员的类型为 VkCompositeAlphaFlagBitsKHR,包含以下值:
// Provided by VK_KHR_surface
typedef enum VkCompositeAlphaFlagBitsKHR {
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR = 0x00000001,
VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR = 0x00000002,
VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR = 0x00000004,
VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR = 0x00000008,
} VkCompositeAlphaFlagBitsKHR;
这些值描述如下:
-
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR:在合成过程中,图像的 alpha 分量(如果存在)将被忽略。相反,图像将被视为具有恒定的 alpha 值 1.0。 -
VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR:在合成过程中,图像的 alpha 分量(如果存在)将被考虑在内。应用程序应已将图像的非 alpha 分量乘以 alpha 分量。 -
VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR:在合成过程中,图像的 alpha 分量(如果存在)将被考虑在内。应用程序不应已将图像的非 alpha 分量乘以 alpha 分量;相反,合成器将在合成期间将图像的非 alpha 分量乘以 alpha 分量。 -
VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR:Vulkan API 不知道演示引擎如何处理图像中的 alpha 分量。相反,应用程序负责使用本机窗口系统命令设置合成 alpha 混合模式。如果应用程序未使用本机窗口系统命令设置混合模式,则将使用平台特定的默认值。
// Provided by VK_KHR_surface
typedef VkFlags VkCompositeAlphaFlagsKHR;
VkCompositeAlphaFlagsKHR 是一种位掩码类型,用于设置零个或多个 VkCompositeAlphaFlagBitsKHR 的掩码。
表面格式支持
要查询表面支持的交换链格式-颜色空间对,请调用:
// Provided by VK_KHR_surface
VkResult vkGetPhysicalDeviceSurfaceFormatsKHR(
VkPhysicalDevice physicalDevice,
VkSurfaceKHR surface,
uint32_t* pSurfaceFormatCount,
VkSurfaceFormatKHR* pSurfaceFormats);
-
physicalDevice是将与要创建的交换链关联的物理设备,如 vkCreateSwapchainKHR 所述。 -
surface是将与交换链关联的表面。 -
pSurfaceFormatCount是一个指向整数的指针,该整数与可用或查询的格式对的数量有关,如下所述。 -
pSurfaceFormats可以是NULL或指向VkSurfaceFormatKHR结构数组的指针。
如果 pSurfaceFormats 为 NULL,则给定 surface 支持的格式对的数量将返回到 pSurfaceFormatCount 中。否则,pSurfaceFormatCount 必须指向由应用程序设置为 pSurfaceFormats 数组中元素数量的变量,并且在返回时,该变量将被实际写入 pSurfaceFormats 的结构数量覆盖。如果 pSurfaceFormatCount 的值小于支持的格式对的数量,则最多会写入 pSurfaceFormatCount 个结构,并且将返回 VK_INCOMPLETE 而不是 VK_SUCCESS,以指示并非返回了所有可用的格式对。
支持的格式对数量必须大于或等于 1。pSurfaceFormats 不能包含 format 值为 VK_FORMAT_UNDEFINED 的条目。
如果 pSurfaceFormats 包含 colorSpace 值为 VK_COLOR_SPACE_SRGB_NONLINEAR_KHR 且 format 值为 UNORM(或 SRGB)格式的条目,并且相应的 SRGB(或 UNORM)格式是 VK_IMAGE_TILING_OPTIMAL 的颜色可渲染格式,则 pSurfaceFormats 必须还包含一个条目,其 colorSpace 的值相同,并且 format 等于相应的 SRGB(或 UNORM)格式。
如果启用了 VK_GOOGLE_surfaceless_query 扩展,则 pSurfaceFormats 中返回的值对于在此物理设备上创建的每个有效表面都将相同,因此 surface 可以为 VK_NULL_HANDLE。
VkSurfaceFormatKHR 结构的定义如下:
// Provided by VK_KHR_surface
typedef struct VkSurfaceFormatKHR {
VkFormat format;
VkColorSpaceKHR colorSpace;
} VkSurfaceFormatKHR;
-
format是与指定表面兼容的 VkFormat。 -
colorSpace是与表面兼容的演示 VkColorSpaceKHR。
要查询表面支持的交换链格式元组,请调用:
// Provided by VK_KHR_get_surface_capabilities2
VkResult vkGetPhysicalDeviceSurfaceFormats2KHR(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
uint32_t* pSurfaceFormatCount,
VkSurfaceFormat2KHR* pSurfaceFormats);
-
physicalDevice是将与要创建的交换链关联的物理设备,如 vkCreateSwapchainKHR 所述。 -
pSurfaceInfo是指向 VkPhysicalDeviceSurfaceInfo2KHR 结构的指针,该结构描述了表面和其他将被 vkCreateSwapchainKHR 消耗的固定参数。 -
pSurfaceFormatCount是一个指向整数的指针,该整数与可用或查询的格式元组的数量有关,如下所述。 -
pSurfaceFormats可以是NULL或指向 VkSurfaceFormat2KHR 结构数组的指针。
vkGetPhysicalDeviceSurfaceFormats2KHR 的行为类似于 vkGetPhysicalDeviceSurfaceFormatsKHR,但可以通过 pNext 链进行扩展。
如果 pSurfaceFormats 为 NULL,则在 pSurfaceFormatCount 中返回给定 surface 支持的格式元组的数量。否则,pSurfaceFormatCount 必须 指向一个由应用程序设置为 pSurfaceFormats 数组中元素数量的变量,并且在返回时,该变量将被实际写入 pSurfaceFormats 的结构数量覆盖。如果 pSurfaceFormatCount 的值小于支持的格式元组的数量,则最多写入 pSurfaceFormatCount 个结构,并返回 VK_INCOMPLETE 而不是 VK_SUCCESS,以指示并非所有可用的值都已返回。
VkSurfaceFormat2KHR 结构的定义如下:
// Provided by VK_KHR_get_surface_capabilities2
typedef struct VkSurfaceFormat2KHR {
VkStructureType sType;
void* pNext;
VkSurfaceFormatKHR surfaceFormat;
} VkSurfaceFormat2KHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
surfaceFormat是一个 VkSurfaceFormatKHR 结构,描述与指定表面兼容的格式-色彩空间对。
如果支持 imageCompressionControlSwapchain 功能,并且 VkImageCompressionPropertiesEXT 结构包含在此结构的 pNext 链中,则它将填充 surfaceFormat 支持的压缩属性。
虽然可呈现图像的 format 指的是每个像素的编码方式,但 colorSpace 决定了呈现引擎如何解释像素值。本文档中的颜色空间指的是特定的颜色空间(由其原色的色度和 CIE Lab 中的白点定义),以及指示图像数据与相对于给定颜色空间的色度之间映射的传递函数。
VkSurfaceFormatKHR::colorSpace 的可能值,指定呈现引擎可以接受的颜色空间如下:
// Provided by VK_KHR_surface
typedef enum VkColorSpaceKHR {
VK_COLOR_SPACE_SRGB_NONLINEAR_KHR = 0,
// Provided by VK_EXT_swapchain_colorspace
VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT = 1000104001,
// Provided by VK_EXT_swapchain_colorspace
VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT = 1000104002,
// Provided by VK_EXT_swapchain_colorspace
VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT = 1000104003,
// Provided by VK_EXT_swapchain_colorspace
VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT = 1000104004,
// Provided by VK_EXT_swapchain_colorspace
VK_COLOR_SPACE_BT709_LINEAR_EXT = 1000104005,
// Provided by VK_EXT_swapchain_colorspace
VK_COLOR_SPACE_BT709_NONLINEAR_EXT = 1000104006,
// Provided by VK_EXT_swapchain_colorspace
VK_COLOR_SPACE_BT2020_LINEAR_EXT = 1000104007,
// Provided by VK_EXT_swapchain_colorspace
VK_COLOR_SPACE_HDR10_ST2084_EXT = 1000104008,
// Provided by VK_EXT_swapchain_colorspace
// VK_COLOR_SPACE_DOLBYVISION_EXT is deprecated, but no reason was given in the API XML
VK_COLOR_SPACE_DOLBYVISION_EXT = 1000104009,
// Provided by VK_EXT_swapchain_colorspace
VK_COLOR_SPACE_HDR10_HLG_EXT = 1000104010,
// Provided by VK_EXT_swapchain_colorspace
VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT = 1000104011,
// Provided by VK_EXT_swapchain_colorspace
VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT = 1000104012,
// Provided by VK_EXT_swapchain_colorspace
VK_COLOR_SPACE_PASS_THROUGH_EXT = 1000104013,
// Provided by VK_EXT_swapchain_colorspace
VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT = 1000104014,
// Provided by VK_AMD_display_native_hdr
VK_COLOR_SPACE_DISPLAY_NATIVE_AMD = 1000213000,
// VK_COLORSPACE_SRGB_NONLINEAR_KHR is a deprecated alias
VK_COLORSPACE_SRGB_NONLINEAR_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
// Provided by VK_EXT_swapchain_colorspace
// VK_COLOR_SPACE_DCI_P3_LINEAR_EXT is a deprecated alias
VK_COLOR_SPACE_DCI_P3_LINEAR_EXT = VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT,
} VkColorSpaceKHR;
-
VK_COLOR_SPACE_SRGB_NONLINEAR_KHR指定支持 sRGB 颜色空间中的图像,根据 sRGB 规范进行编码。 -
VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT指定支持 Display-P3 颜色空间中的图像,使用 Display-P3 传递函数进行编码。 -
VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT指定支持扩展 sRGB 颜色空间中的图像,使用线性传递函数进行编码。 -
VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT指定支持扩展 sRGB 颜色空间中的图像,根据 scRGB 规范进行编码。 -
VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT指定支持 Display-P3 颜色空间中的图像,使用线性传递函数进行编码。 -
VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT指定支持 DCI-P3 颜色空间中的图像,根据 DCI-P3 规范进行编码。请注意,此类图像中的值被呈现引擎解释为 XYZ 编码的颜色数据。 -
VK_COLOR_SPACE_BT709_LINEAR_EXT指定支持 BT709 颜色空间中的图像,使用线性传递函数进行编码。 -
VK_COLOR_SPACE_BT709_NONLINEAR_EXT指定支持 BT709 颜色空间中的图像,根据 BT709 规范进行编码。 -
VK_COLOR_SPACE_BT2020_LINEAR_EXT指定支持 BT2020 颜色空间中的图像,使用线性传递函数进行编码。 -
VK_COLOR_SPACE_HDR10_ST2084_EXT指定支持 HDR10 (BT2020) 颜色空间中的图像,根据 SMPTE ST2084 感知量化器 (PQ) 规范进行编码。 -
VK_COLOR_SPACE_HDR10_HLG_EXT指定支持 HDR10 (BT2020) 颜色空间中的图像,根据混合对数伽马 (HLG) 规范进行编码。 -
VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT指定支持 Adobe RGB 颜色空间中的图像,使用线性传递函数进行编码。 -
VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT指定支持 Adobe RGB 颜色空间中的图像,根据 Adobe RGB 规范(近似伽马 2.2)进行编码。 -
VK_COLOR_SPACE_PASS_THROUGH_EXT指定颜色分量“按原样”使用。这旨在允许应用程序提供此处未描述的颜色空间的数据。 -
VK_COLOR_SPACE_DISPLAY_NATIVE_AMD指定支持显示器的原生颜色空间。这与支持 AMD FreeSync2 标准的显示器的颜色空间期望相匹配。
|
在 |
|
在此扩展的旧版本中, |
|
在 |
|
注意
对于传统的“线性”或非伽马传递函数颜色空间,请使用 |
演示引擎将 R、G 和 B 分量的像素值解释为已使用适当的传递函数进行编码。应用程序**应该**确保已应用适当的传递函数。纹理输出格式转换 要求所有实现在着色器写入 sRGB 像素格式图像时,隐式地对 R、G 和 B 分量应用 sRGB EOTF-1,这对于 sRGB 颜色空间很有用。对于具有其他像素格式的 sRGB 颜色空间或其他非线性颜色空间,应用程序**可以**在着色器中显式应用传递函数。A 通道始终被解释为线性编码。
此扩展定义了 VkColorSpaceKHR 的枚举,这些枚举对应于以下颜色空间
| 名称 | 红色基色 | 绿色基色 | 蓝色基色 | 白点 | 传递函数 |
|---|---|---|---|---|---|
DCI-P3 |
1.000, 0.000 |
0.000, 1.000 |
0.000, 0.000 |
0.3333, 0.3333 |
DCI P3 |
Display-P3 |
0.680, 0.320 |
0.265, 0.690 |
0.150, 0.060 |
0.3127, 0.3290 (D65) |
Display-P3 |
BT709 |
0.640, 0.330 |
0.300, 0.600 |
0.150, 0.060 |
0.3127, 0.3290 (D65) |
BT709 |
sRGB |
0.640, 0.330 |
0.300, 0.600 |
0.150, 0.060 |
0.3127, 0.3290 (D65) |
sRGB |
扩展 sRGB |
0.640, 0.330 |
0.300, 0.600 |
0.150, 0.060 |
0.3127, 0.3290 (D65) |
scRGB |
HDR10_ST2084 |
0.708, 0.292 |
0.170, 0.797 |
0.131, 0.046 |
0.3127, 0.3290 (D65) |
ST2084 PQ |
HDR10_HLG |
0.708, 0.292 |
0.170, 0.797 |
0.131, 0.046 |
0.3127, 0.3290 (D65) |
HLG |
Adobe RGB |
0.640, 0.330 |
0.210, 0.710 |
0.150, 0.060 |
0.3127, 0.3290 (D65) |
Adobe RGB |
传递函数在Khronos 数据格式规范的“传递函数”章节中描述。
Display-P3 OETF 除外,它是
其中 L 是颜色分量的线性值,E 是编码值(存储在内存中的图像中)。
|
对于大多数用途,sRGB OETF 是等效的。 |
表面呈现模式支持
要查询表面的支持呈现模式,请调用
// Provided by VK_KHR_surface
VkResult vkGetPhysicalDeviceSurfacePresentModesKHR(
VkPhysicalDevice physicalDevice,
VkSurfaceKHR surface,
uint32_t* pPresentModeCount,
VkPresentModeKHR* pPresentModes);
-
physicalDevice是将与要创建的交换链关联的物理设备,如 vkCreateSwapchainKHR 所述。 -
surface是将与交换链关联的表面。 -
pPresentModeCount是一个指向整数的指针,该整数与可用或查询的呈现模式数量有关,如下所述。 -
pPresentModes可以是NULL或指向 VkPresentModeKHR 值数组的指针,指示支持的呈现模式。
如果 pPresentModes 为 NULL,则 pPresentModeCount 中返回给定 surface 支持的呈现模式数量。否则,pPresentModeCount **必须**指向由应用程序设置为 pPresentModes 数组中元素数量的变量,并且在返回时,该变量将被实际写入 pPresentModes 的值的数量覆盖。如果 pPresentModeCount 的值小于支持的呈现模式数量,则最多写入 pPresentModeCount 个值,并且将返回 VK_INCOMPLETE 而不是 VK_SUCCESS,以指示并非所有可用模式都已返回。
如果启用了 VK_GOOGLE_surfaceless_query 扩展,并且 surface 为 VK_NULL_HANDLE,则 pPresentModes 中返回的值将仅指示对 VK_PRESENT_MODE_FIFO_KHR、VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR 和 VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR 的支持。要查询对任何其他呈现模式的支持,**必须**在 surface 中提供有效的句柄。
或者,要查询表面与其他选定的固定交换链创建参数组合支持的呈现模式,请调用
// Provided by VK_EXT_full_screen_exclusive
VkResult vkGetPhysicalDeviceSurfacePresentModes2EXT(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
uint32_t* pPresentModeCount,
VkPresentModeKHR* pPresentModes);
-
physicalDevice是将与要创建的交换链关联的物理设备,如 vkCreateSwapchainKHR 所述。 -
pSurfaceInfo是指向 VkPhysicalDeviceSurfaceInfo2KHR 结构的指针,该结构描述了表面和其他将被 vkCreateSwapchainKHR 消耗的固定参数。 -
pPresentModeCount是一个指向整数的指针,该整数与可用或查询的呈现模式数量有关,如下所述。 -
pPresentModes可以是NULL或指向 VkPresentModeKHR 值数组的指针,指示支持的呈现模式。
vkGetPhysicalDeviceSurfacePresentModes2EXT 的行为类似于 vkGetPhysicalDeviceSurfacePresentModesKHR,并且能够通过链接的输入结构指定扩展输入。
vkGetPhysicalDeviceSurfacePresentModesKHR::pPresentModes 数组元素的可能值,指示表面的支持呈现模式,是
// Provided by VK_KHR_surface
typedef enum VkPresentModeKHR {
VK_PRESENT_MODE_IMMEDIATE_KHR = 0,
VK_PRESENT_MODE_MAILBOX_KHR = 1,
VK_PRESENT_MODE_FIFO_KHR = 2,
VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3,
// Provided by VK_KHR_shared_presentable_image
VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR = 1000111000,
// Provided by VK_KHR_shared_presentable_image
VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR = 1000111001,
// Provided by VK_EXT_present_mode_fifo_latest_ready
VK_PRESENT_MODE_FIFO_LATEST_READY_EXT = 1000361000,
} VkPresentModeKHR;
-
VK_PRESENT_MODE_IMMEDIATE_KHR指定演示引擎不会等待垂直消隐期来更新当前图像,这意味着此模式**可能**会导致可见的撕裂。不需要内部排队呈现请求,因为请求会立即应用。 -
VK_PRESENT_MODE_MAILBOX_KHR指定显示引擎等待下一个垂直消隐期来更新当前图像。 不会 出现画面撕裂现象。 内部使用一个单入口队列来保存待处理的呈现请求。 如果队列已满,收到新的呈现请求时,新请求将替换现有条目,并且与先前条目关联的任何图像都可供应用程序重用。 在队列非空的每个垂直消隐期间,都会从队列中删除并处理一个请求。 -
VK_PRESENT_MODE_FIFO_KHR指定显示引擎等待下一个垂直消隐期来更新当前图像。 不会 出现画面撕裂现象。 内部使用一个队列来保存待处理的呈现请求。 新请求会被追加到队列末尾,并且在队列非空的每个垂直消隐期间,都会从队列开头删除并处理一个请求。 这是presentMode唯一必须支持的值。 -
VK_PRESENT_MODE_FIFO_RELAXED_KHR指定显示引擎通常会等待下一个垂直消隐期来更新当前图像。 如果自上次更新当前图像以来已经经过了一个垂直消隐期,则显示引擎不会等待另一个垂直消隐期进行更新,这意味着在这种情况下,此模式可能会导致可见的画面撕裂。 此模式对于减少视觉卡顿很有用,应用程序大多会在下一个垂直消隐期之前呈现新图像,但偶尔可能会延迟,并在下一个垂直消隐期之后立即呈现新图像。 内部使用一个队列来保存待处理的呈现请求。 新请求会被追加到队列末尾,并且在队列非空的每个垂直消隐期间或之后,都会从队列开头删除并处理一个请求。 -
VK_PRESENT_MODE_FIFO_LATEST_READY_EXT指定显示引擎等待下一个垂直消隐期来更新当前图像。 不会 出现画面撕裂现象。 内部使用一个队列来保存待处理的呈现请求。 新请求会被追加到队列末尾。 在每个垂直消隐期,显示引擎都会从队列开头出队所有已准备好呈现的连续请求。 如果使用VK_GOOGLE_display_timing来提供目标呈现时间,显示引擎将检查每个图像的指定时间。 如果目标呈现时间小于或等于当前时间,则显示引擎将出队图像并检查下一个。 将呈现最后一个出队请求的图像。 其他出队的请求将被丢弃。 -
VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR指定显示引擎和应用程序可以并发访问单个图像,该图像称为共享可呈现图像。 仅当收到新的呈现请求时,才需要显示引擎更新当前图像。 因此,应用程序在需要更新时必须发出呈现请求。 但是,显示引擎可能在任何时候更新当前图像,这意味着此模式可能会导致可见的画面撕裂。 -
VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR指定显示引擎和应用程序可以并发访问单个图像,该图像称为共享可呈现图像。 显示引擎在其常规刷新周期中定期更新当前图像。 应用程序只需要发出一个初始呈现请求,此后显示引擎必须更新当前图像,而无需任何其他呈现请求。 应用程序可以通过发出呈现请求来指示图像内容已更新,但这不能保证更新的时间。 如果未正确计时对图像的渲染,此模式可能会导致可见的画面撕裂。
为表面创建的交换链的可呈现图像所支持的 VkImageUsageFlagBits 可能会因呈现模式而异,可以按照下表确定
| 呈现模式 | 图像使用标志 |
|---|---|
|
VkSurfaceCapabilitiesKHR:: |
|
VkSurfaceCapabilitiesKHR:: |
|
VkSurfaceCapabilitiesKHR:: |
|
VkSurfaceCapabilitiesKHR:: |
|
VkSurfaceCapabilitiesKHR:: |
|
VkSharedPresentSurfaceCapabilitiesKHR:: |
|
VkSharedPresentSurfaceCapabilitiesKHR:: |
|
作为参考, |
全屏独占控制
将 fullScreenExclusive 设置为 VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT 创建的交换链必须使用以下命令显式获取和释放独占全屏访问权限。
要获取交换链的独占全屏访问权限,请调用
// Provided by VK_EXT_full_screen_exclusive
VkResult vkAcquireFullScreenExclusiveModeEXT(
VkDevice device,
VkSwapchainKHR swapchain);
-
device是与swapchain关联的设备。 -
swapchain是要获取独占全屏访问权限的交换链。
返回 VK_SUCCESS 值表示 swapchain 成功获取了独占全屏访问权限。 交换链将保留此独占性,直到应用程序使用 vkReleaseFullScreenExclusiveModeEXT 释放独占全屏访问权限、销毁交换链,或者如果任何交换链命令返回 VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT,则表示由于平台特定的更改而丢失了该模式。
如果交换链无法获取对显示器的独占全屏访问权限,则返回 VK_ERROR_INITIALIZATION_FAILED。即使此命令失败,或者交换链命令返回 VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT,应用程序可以尝试再次为同一个交换链获取独占全屏访问权限。
要从交换链释放独占全屏访问权限,请调用
// Provided by VK_EXT_full_screen_exclusive
VkResult vkReleaseFullScreenExclusiveModeEXT(
VkDevice device,
VkSwapchainKHR swapchain);
-
device是与swapchain关联的设备。 -
swapchain是要从中释放独占全屏访问权限的交换链。
|
在调用此函数后,应用程序将无法呈现到 |
设备组查询
代表多个物理设备的逻辑设备可能支持从多个物理设备上的图像进行呈现,或组合来自多个物理设备的图像。
要查询这些功能,请调用
// Provided by VK_VERSION_1_1 with VK_KHR_swapchain, VK_KHR_device_group with VK_KHR_surface
VkResult vkGetDeviceGroupPresentCapabilitiesKHR(
VkDevice device,
VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities);
-
device是逻辑设备。 -
pDeviceGroupPresentCapabilities是指向 VkDeviceGroupPresentCapabilitiesKHR 结构的指针,其中返回设备的功能。
VkDeviceGroupPresentCapabilitiesKHR 结构的定义如下
// Provided by VK_VERSION_1_1 with VK_KHR_swapchain, VK_KHR_device_group with VK_KHR_surface
typedef struct VkDeviceGroupPresentCapabilitiesKHR {
VkStructureType sType;
void* pNext;
uint32_t presentMask[VK_MAX_DEVICE_GROUP_SIZE];
VkDeviceGroupPresentModeFlagsKHR modes;
} VkDeviceGroupPresentCapabilitiesKHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
presentMask是一个VK_MAX_DEVICE_GROUP_SIZE个uint32_t掩码的数组,其中元素 i 处的掩码如果物理设备 i 具有呈现引擎则为非零,并且如果物理设备 i 可以呈现来自物理设备 j 的交换链图像,则元素 i 中设置了位 j。如果元素 i 为非零,则必须设置位 i。 -
modes是 VkDeviceGroupPresentModeFlagBitsKHR 的位掩码,指示支持哪些设备组呈现模式。
modes 始终设置了 VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR。
呈现图像时,也会在 VkDeviceGroupPresentInfoKHR::mode 中使用呈现模式标志。
如果设备组仅包含单个物理设备,则 modes 必须等于 VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR。
可以在 VkDeviceGroupPresentCapabilitiesKHR::modes 中设置的位,指示支持哪些设备组呈现模式,是
// Provided by VK_VERSION_1_1 with VK_KHR_swapchain, VK_KHR_device_group with VK_KHR_surface
typedef enum VkDeviceGroupPresentModeFlagBitsKHR {
VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR = 0x00000001,
VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR = 0x00000002,
VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR = 0x00000004,
VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR = 0x00000008,
} VkDeviceGroupPresentModeFlagBitsKHR;
-
VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR指定具有呈现引擎的任何物理设备可以呈现其自己的交换链图像。 -
VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR指定具有呈现引擎的任何物理设备可以呈现来自其presentMask中任何物理设备的交换链图像。 -
VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR指定具有呈现引擎的任何物理设备可以呈现来自其presentMask中任何物理设备的交换链图像的总和。 -
VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR指定具有呈现引擎的多个物理设备可以分别呈现其自己的交换链图像。
// Provided by VK_VERSION_1_1 with VK_KHR_swapchain, VK_KHR_device_group with VK_KHR_surface
typedef VkFlags VkDeviceGroupPresentModeFlagsKHR;
VkDeviceGroupPresentModeFlagsKHR 是用于设置零个或多个 VkDeviceGroupPresentModeFlagBitsKHR 掩码的位掩码类型。
某些表面可能无法使用所有设备组呈现模式。
要查询特定表面支持的设备组呈现模式,请调用
// Provided by VK_VERSION_1_1 with VK_KHR_swapchain, VK_KHR_device_group with VK_KHR_surface
VkResult vkGetDeviceGroupSurfacePresentModesKHR(
VkDevice device,
VkSurfaceKHR surface,
VkDeviceGroupPresentModeFlagsKHR* pModes);
-
device是逻辑设备。 -
surface是表面。 -
pModes是指向 VkDeviceGroupPresentModeFlagsKHR 的指针,其中返回该表面支持的设备组呈现模式。
此命令返回的模式不是固定的,并且可能会因表面移动、调整大小或被遮挡而发生变化。这些模式必须是 vkGetDeviceGroupPresentCapabilitiesKHR 返回的模式的子集。
或者,要查询表面结合其他选定的固定交换链创建参数所支持的设备组呈现模式,请调用
// Provided by VK_EXT_full_screen_exclusive with VK_KHR_device_group or VK_VERSION_1_1
VkResult vkGetDeviceGroupSurfacePresentModes2EXT(
VkDevice device,
const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
VkDeviceGroupPresentModeFlagsKHR* pModes);
-
device是逻辑设备。 -
pSurfaceInfo是指向 VkPhysicalDeviceSurfaceInfo2KHR 结构的指针,该结构描述了表面和其他将被 vkCreateSwapchainKHR 消耗的固定参数。 -
pModes是指向 VkDeviceGroupPresentModeFlagsKHR 的指针,其中返回该表面支持的设备组呈现模式。
vkGetDeviceGroupSurfacePresentModes2EXT 的行为类似于 vkGetDeviceGroupSurfacePresentModesKHR,但可以通过链式输入结构指定扩展输入。
当使用 VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR 时,应用程序可能需要知道在每个物理设备上本地呈现时,表面的哪些区域被使用。交换链图像到此表面的呈现只需要在由该命令返回的区域中具有有效内容。
要查询物理设备上呈现中使用的矩形集合,请调用
// Provided by VK_VERSION_1_1 with VK_KHR_swapchain, VK_KHR_device_group with VK_KHR_surface
VkResult vkGetPhysicalDevicePresentRectanglesKHR(
VkPhysicalDevice physicalDevice,
VkSurfaceKHR surface,
uint32_t* pRectCount,
VkRect2D* pRects);
-
physicalDevice是物理设备。 -
surface是表面。 -
pRectCount是一个指向与可用或查询的矩形数量相关的整数的指针,如下所述。 -
pRects可以是NULL,也可以是指向 VkRect2D 结构数组的指针。
如果 pRects 为 NULL,则当呈现给定的 surface 时使用的矩形数量将在 pRectCount 中返回。否则,pRectCount 必须指向应用程序设置为 pRects 数组中元素数量的变量,并且在返回时,该变量将被实际写入 pRects 的结构数量覆盖。如果 pRectCount 的值小于矩形的数量,则最多将写入 pRectCount 个结构,并且将返回 VK_INCOMPLETE 而不是 VK_SUCCESS,以指示并非所有可用的矩形都被返回。
此命令返回的值不是不变的,并且可能会响应表面的移动、调整大小或被遮挡而更改。
此命令返回的矩形必须不重叠。
显示定时查询
传统的游戏和实时动画应用程序经常使用 VK_PRESENT_MODE_FIFO_KHR,以便在演示引擎显示器的给定刷新周期 (RC) 的垂直消隐期间更新可呈现图像。 这避免了被称为撕裂的视觉异常。
然而,将图像的呈现与 RC 同步并不能防止所有形式的视觉异常。当每个可呈现图像的几何图形没有针对该图像何时显示进行精确定位时,就会发生卡顿。几何图形在某些 RC 中可能显得移动得太少,而在其他 RC 中则显得移动得太多。有时,当同一图像用于多个 RC 时,动画似乎会冻结。
为了尽量减少卡顿,应用程序需要正确地定位几何图形,以使其在可呈现图像显示给用户时正确。为了实现这一点,应用程序需要有关演示引擎显示器的各种定时信息。他们需要知道可呈现图像实际呈现的时间,以及它们可能被呈现的时间。应用程序还需要告诉演示引擎在不早于给定时间显示图像。这可以使应用程序的动画对用户看起来平滑,而不会出现卡顿。VK_GOOGLE_display_timing 扩展允许应用程序满足这些需求。
演示引擎的显示器通常会定期刷新显示给用户的像素。该周期可以是固定的,也可以是可变的。在许多情况下,演示引擎与固定刷新率 (FRR) 显示技术相关联,具有固定的刷新率 (RR,例如 60Hz)。在某些情况下,演示引擎与可变刷新率 (VRR) 显示技术相关联,其中每个刷新周期 (RC) 的长度可能不同。此扩展将 VRR 显示视为 FRR。
要查询演示引擎显示器的刷新周期 (RC) 的持续时间,请调用
// Provided by VK_GOOGLE_display_timing
VkResult vkGetRefreshCycleDurationGOOGLE(
VkDevice device,
VkSwapchainKHR swapchain,
VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties);
-
device是与swapchain关联的设备。 -
swapchain是要获取刷新持续时间的交换链。 -
pDisplayTimingProperties是指向VkRefreshCycleDurationGOOGLE结构的指针。
VkRefreshCycleDurationGOOGLE 结构定义为
// Provided by VK_GOOGLE_display_timing
typedef struct VkRefreshCycleDurationGOOGLE {
uint64_t refreshDuration;
} VkRefreshCycleDurationGOOGLE;
-
refreshDuration是从一个刷新周期开始到下一个刷新周期开始的纳秒数。
|
应用程序渲染和呈现新图像的速率称为图像呈现率(IPR,也称为帧率)。IPR 的倒数,即每个图像呈现之间的持续时间,称为图像呈现持续时间(IPD)。为了提供流畅、无卡顿的动画,应用程序希望其 IPD 是 为了确定显示器的目标 IPD(即 应用程序的 IPD 可能需要调整,因为应用程序几何位置的不同视图可能需要不同的渲染时间。例如,看天空可能比看房间里多个复杂的物体需要更少的渲染时间。一般来说,最好不要频繁更改 IPD,因为这可能会导致视觉异常。由于图像延迟而增大 IPD 的调整应该快速进行,但是只有当 VkPastPresentationTimingGOOGLE 结构的 |
实现将维护有关先前呈现的定时信息的有限历史记录。由于呈现引擎的异步性质,给定的 vkQueuePresentKHR 命令的定时信息将在稍后一段时间可用。这些时间值可以异步查询,如果可用,将会返回。所有时间值均以纳秒为单位,相对于单调递增的时钟(例如,Android 和 Linux 上的 CLOCK_MONOTONIC(请参阅 clock_gettime(2)))。
要异步查询呈现引擎,以获取有关先前到一个给定交换链的一个或多个呈现的最新可用定时信息,请调用
// Provided by VK_GOOGLE_display_timing
VkResult vkGetPastPresentationTimingGOOGLE(
VkDevice device,
VkSwapchainKHR swapchain,
uint32_t* pPresentationTimingCount,
VkPastPresentationTimingGOOGLE* pPresentationTimings);
-
device是与swapchain关联的设备。 -
swapchain是要获取演示定时信息持续时间的交换链。 -
pPresentationTimingCount是一个指向与要查询的VkPastPresentationTimingGOOGLE结构的数量相关的整数的指针,如下所述。 -
pPresentationTimings可以是NULL,也可以是指向VkPastPresentationTimingGOOGLE结构数组的指针。
如果 pPresentationTimings 为 NULL,则会在 pPresentationTimingCount 中返回给定 swapchain 的最新可用定时记录的数量。否则,pPresentationTimingCount 必须指向一个由用户设置为 pPresentationTimings 数组中元素数量的变量,并且在返回时,该变量将被实际写入 pPresentationTimings 的结构数量覆盖。如果 pPresentationTimingCount 的值小于最新可用定时记录的数量,则最多会写入 pPresentationTimingCount 个结构,并且会返回 VK_INCOMPLETE 而不是 VK_SUCCESS,以指示并非所有可用定时记录都已返回。
VkPastPresentationTimingGOOGLE 结构的定义如下:
// Provided by VK_GOOGLE_display_timing
typedef struct VkPastPresentationTimingGOOGLE {
uint32_t presentID;
uint64_t desiredPresentTime;
uint64_t actualPresentTime;
uint64_t earliestPresentTime;
uint64_t presentMargin;
} VkPastPresentationTimingGOOGLE;
-
presentID是应用程序提供的值,该值通过 VkPresentTimeGOOGLE::presentID传递给先前的vkQueuePresentKHR命令(请参见下文)。它可以用来唯一标识与 vkQueuePresentKHR 命令的先前呈现。 -
desiredPresentTime是应用程序提供的值,该值通过 VkPresentTimeGOOGLE::desiredPresentTime传递给先前的 vkQueuePresentKHR 命令。如果非零,则应用程序使用它来指示图像的呈现时间不应早于desiredPresentTime。 -
actualPresentTime是swapchain的图像实际显示的时间。 -
earliestPresentTime是swapchain的图像可以显示的时间。如果应用程序请求图像的呈现时间不早于 VkPresentTimeGOOGLE::desiredPresentTime,则该时间可能与actualPresentTime不同。 -
presentMargin指示vkQueuePresentKHR命令相对于它需要处理且仍然能够在earliestPresentTime呈现的时间的提前处理程度。
给定 swapchain 和 presentID 的结果仅从 vkGetPastPresentationTimingGOOGLE 返回一次。
应用程序可以使用 VkPastPresentationTimingGOOGLE 值来偶尔调整其时序。例如,如果 actualPresentTime 比预期晚(例如,晚了一个 refreshDuration),应用程序可能会将其目标 IPD 增加为 refreshDuration 的更高倍数(例如,将其帧率从 60Hz 降低到 30Hz)。如果 actualPresentTime 和 earliestPresentTime 始终不同,并且如果 presentMargin 始终足够大,则应用程序可能会将其目标 IPD 减少为 refreshDuration 的较小倍数(例如,将其帧率从 30Hz 提高到 60Hz)。如果 actualPresentTime 和 earliestPresentTime 相同,并且如果 presentMargin 始终很高,则应用程序可能会延迟其输入-渲染-呈现循环的开始时间,以便减少用户输入和相应呈现之间的延迟(始终保留一些余量,以防新图像的渲染时间比之前的图像长)。如果应用程序希望其目标 IPD 始终与 refreshDuration 相同,也可以调整功能,直到 actualPresentTime 永远不会延迟且 presentMargin 令人满意为止。
为使用 VK_PRESENT_MODE_FIFO_KHR 创建的交换链描述了完整的 VK_GOOGLE_display_timing 扩展语义。例如,必须遵循 VkPresentTimeGOOGLE::desiredPresentTime 的非零值,并且 vkGetPastPresentationTimingGOOGLE 应该返回一个 VkPastPresentationTimingGOOGLE 结构,其中包含使用 vkQueuePresentKHR 呈现的所有图像的有效值。其他呈现模式的语义如下
-
VK_PRESENT_MODE_IMMEDIATE_KHR。呈现引擎可能会忽略VkPresentTimeGOOGLE::desiredPresentTime的非零值,而倾向于立即呈现。VkPastPresentationTimingGOOGLE::earliestPresentTime的值必须与VkPastPresentationTimingGOOGLE::actualPresentTime相同,后者应该是呈现引擎显示图像的时间。 -
VK_PRESENT_MODE_MAILBOX_KHR。将此呈现模式与此扩展一起使用的目的是处理图像呈现延迟的情况,并且下一个图像会很快呈现以在下一个垂直消隐周期替换它。对于显示给用户的图像,VkPastPresentationTimingGOOGLE::actualPresentTime的值必须是显示图像的时间。对于未显示给用户的图像,vkGetPastPresentationTimingGOOGLE可能不返回VkPastPresentationTimingGOOGLE结构,或者它可能返回一个VkPastPresentationTimingGOOGLE结构,其中VkPastPresentationTimingGOOGLE::actualPresentTime和VkPastPresentationTimingGOOGLE::earliestPresentTime的值都为零。应用程序可以提交具有VkPresentTimeGOOGLE::desiredPresentTime值的图像,以便可能不会显示新图像。例如,如果VkPresentTimeGOOGLE::desiredPresentTime在未来足够远的时间,以至于在调用vkQueuePresentKHR来呈现另一个图像之前没有呈现图像,则第一个图像将不会显示给用户。如果应用程序继续这样做,则呈现可能不会显示新图像。 -
VK_PRESENT_MODE_FIFO_RELAXED_KHR。对于及时呈现以在下一个垂直消隐周期显示的图像,其语义与VK_PRESENT_MODE_FIFO_KHR相同。对于呈现较晚并在垂直消隐周期开始后显示(即出现撕裂)的图像,VkPastPresentationTimingGOOGLE的值可能被视为图像在垂直消隐周期开始时显示,或者可能被视为与VK_PRESENT_MODE_IMMEDIATE_KHR相同。
呈现等待
希望通过监视呈现过程何时完成来控制应用程序节奏,以限制排队等待呈现的未完成图像数量的应用程序,需要在呈现过程中使用一种被信号通知的方法。
使用 VK_GOOGLE_display_timing 扩展,应用程序可以发现图像何时呈现,但只能异步发现。
提供一种机制,使应用程序可以阻塞,等待呈现过程的特定步骤完成,这样可以控制未完成工作量(因此,控制响应用户输入或渲染环境变化时潜在的延迟)。
VK_KHR_present_wait 扩展允许应用程序在 vkQueuePresentKHR 调用时,通过传递 VkPresentIdKHR 结构来告知呈现引擎,它计划等待呈现。然后,可以将该结构中传递的 presentId 传递给将来的 vkWaitForPresentKHR 调用,以使应用程序阻塞直到该呈现完成。
WSI 交换链
交换链对象(也称为交换链)提供了将渲染结果呈现到表面的能力。交换链对象由 VkSwapchainKHR 句柄表示
// Provided by VK_KHR_swapchain
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSwapchainKHR)
交换链是一个与表面关联的可呈现图像数组的抽象。可呈现图像由平台创建的 VkImage 对象表示。一次显示一个图像(可以是多视图/立体 3D 表面的数组图像),但可以排队多个图像进行呈现。应用程序渲染到图像,然后将图像排队以呈现到表面。
一个本机窗口不能同时与多个非已销毁的交换链关联。此外,不能为与非 Vulkan 图形 API 表面关联的本机窗口创建交换链。
|
呈现引擎是平台合成器或显示引擎的抽象。 呈现引擎相对于应用程序和/或逻辑设备可能是同步的或异步的。 某些实现可能使用设备的图形队列或专用呈现硬件来执行呈现。 |
交换链的可呈现图像归呈现引擎所有。应用程序可以从呈现引擎获取可呈现图像的使用权。可呈现图像的使用必须仅在图像由 vkAcquireNextImageKHR 返回之后,并且在由 vkQueuePresentKHR 释放之前进行。这包括转换图像布局和渲染命令。
应用程序可以通过 vkAcquireNextImageKHR 获取可呈现图像的使用权。在获取可呈现图像之后,并且在修改它之前,应用程序必须使用同步原语来确保演示引擎已完成从该图像的读取。然后,应用程序可以转换图像的布局,向其排队渲染命令等。最后,应用程序使用 vkQueuePresentKHR 呈现图像,这将释放对图像的获取。如果设备未使用该图像,应用程序可以通过 vkReleaseSwapchainImagesEXT 释放对图像的获取,并跳过呈现操作。
演示引擎控制应用程序获取可呈现图像的顺序。
|
这允许平台处理需要在演示后无序返回图像的情况。同时,它允许应用程序在初始化时而不是在其主循环中生成引用交换链中所有图像的命令缓冲区。 |
以下描述了这一切是如何工作的。
如果使用设置为 VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR 或 VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR 的 presentMode 创建交换链,则可以获取单个可呈现图像,称为共享可呈现图像。应用程序和演示引擎可以同时访问共享的可呈现图像,而无需在初始呈现后转换图像的布局。
-
对于
VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR,仅在呈现后才需要演示引擎更新到共享可呈现图像的最新内容。应用程序必须调用vkQueuePresentKHR以保证更新。但是,演示引擎可以随时从中更新。 -
对于
VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR,演示引擎将在每个刷新周期中自动呈现共享可呈现图像的最新内容。应用程序仅需首次调用vkQueuePresentKHR,此后,演示引擎将无需进一步的呈现调用即可从中更新。应用程序可以通过调用vkQueuePresentKHR来指示图像内容已更新,但这不能保证更新发生的时间。
演示引擎可以在首次呈现后随时访问共享的可呈现图像。为避免撕裂,应用程序应该与演示引擎协调访问。这需要通过平台特定的机制获取演示引擎定时信息,并确保颜色附件写入在演示引擎刷新周期的预期部分期间可用。
|
|
为了在渲染到共享可呈现图像时查询交换链的状态,请调用
// Provided by VK_KHR_shared_presentable_image
VkResult vkGetSwapchainStatusKHR(
VkDevice device,
VkSwapchainKHR swapchain);
-
device是与swapchain关联的设备。 -
swapchain是要查询的交换链。
vkGetSwapchainStatusKHR 的可能返回值应该按如下方式解释
-
VK_SUCCESS指定演示引擎正在根据交换链的 VkPresentModeKHR 呈现共享可呈现图像的内容。 -
VK_SUBOPTIMAL_KHR交换链不再与表面属性完全匹配,但演示引擎正在根据交换链的 VkPresentModeKHR 呈现共享可呈现图像的内容。 -
VK_ERROR_OUT_OF_DATE_KHR表面已更改,不再与交换链兼容。 -
VK_ERROR_SURFACE_LOST_KHR表面不再可用。
|
交换链状态可能由实现缓存,因此当使用 |
要创建交换链,请调用
// Provided by VK_KHR_swapchain
VkResult vkCreateSwapchainKHR(
VkDevice device,
const VkSwapchainCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSwapchainKHR* pSwapchain);
-
device是为其创建交换链的设备。 -
pCreateInfo是一个指向 VkSwapchainCreateInfoKHR 结构的指针,该结构指定了已创建交换链的参数。 -
pAllocator是用于为主机内存分配器分配的内存的分配器,当没有更具体的分配器可用时,该分配器用于交换链对象(请参阅 内存分配)。 -
pSwapchain是一个指向 VkSwapchainKHR 句柄的指针,创建的交换链对象将在此句柄中返回。
如上所述,如果 vkCreateSwapchainKHR 成功,它将返回一个交换链的句柄,该交换链包含至少 pCreateInfo->minImageCount 个可呈现图像的数组。
在应用程序获取时,可呈现图像可以以任何方式使用,这与非可呈现图像的使用方式相同。可呈现图像等效于使用以下 VkImageCreateInfo 参数创建的非可呈现图像
VkImageCreateInfo 字段 |
值 |
|---|---|
|
如果设置了 如果设置了 如果设置了 所有其他位均未设置 |
|
|
|
|
|
{ |
|
1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
在销毁交换链之前,必须不销毁 pCreateInfo->surface。
如果 oldSwapchain 是 VK_NULL_HANDLE,并且 pCreateInfo->surface 引用的本机窗口已经与 Vulkan 交换链关联,则必须返回 VK_ERROR_NATIVE_WINDOW_IN_USE_KHR。
如果 pCreateInfo->surface 引用的本机窗口已经与非 Vulkan 图形 API 表面关联,则必须返回 VK_ERROR_NATIVE_WINDOW_IN_USE_KHR。
在销毁所有关联的 Vulkan 交换链之前,pCreateInfo->surface 引用的本机窗口必须不与非 Vulkan 图形 API 表面关联。
如果逻辑设备丢失,vkCreateSwapchainKHR 将返回 VK_ERROR_DEVICE_LOST。VkSwapchainKHR 是 device 的子项,必须在 device 之前销毁。但是,VkSurfaceKHR 不是任何 VkDevice 的子项,并且不受丢失设备的影响。成功重新创建 VkDevice 后,如果销毁了先前的 VkSwapchainKHR,则可以使用相同的 VkSurfaceKHR 来创建新的 VkSwapchainKHR。
如果 pCreateInfo 的 oldSwapchain 参数是有效的交换链,并且具有独占全屏访问权限,则该访问权限将从 pCreateInfo->oldSwapchain 中释放。如果命令在这种情况下成功,则新创建的交换链将自动从 pCreateInfo->oldSwapchain 获取独占全屏访问权限。
|
这种隐式传输旨在避免退出和进入全屏独占模式,否则可能会导致显示出现不必要的视觉更新。 |
在某些情况下,如果请求应用程序控制的独占全屏模式,但由于某些特定于实现的 原因,对于所提供的特定参数组合,独占全屏访问不可用,则交换链的创建可能会失败。如果发生这种情况,将返回 VK_ERROR_INITIALIZATION_FAILED。
|
特别是,如果 |
如果 VkSwapchainCreateInfoKHR 的 pNext 链包含 VkSwapchainPresentBarrierCreateInfoNV 结构,则该结构包含特定于 present barrier 的其他交换链创建参数。如果当前系统的状态限制了 present barrier 功能 VkSurfaceCapabilitiesPresentBarrierNV 的使用,或者交换链本身不满足所有必需的条件,则交换链的创建可能会失败。在这种情况下,将返回 VK_ERROR_INITIALIZATION_FAILED。
当 VkSwapchainCreateInfoKHR 中的 VkSurfaceKHR 是显示表面时,显示表面的 VkDisplaySurfaceCreateInfoKHR 中的 VkDisplayModeKHR 与特定的 VkDisplayKHR 相关联。如果应用程序未获取该 VkDisplayKHR,则交换链的创建可能会失败。在这种情况下,将返回 VK_ERROR_INITIALIZATION_FAILED。
VkSwapchainCreateInfoKHR 结构定义如下:
// Provided by VK_KHR_swapchain
typedef struct VkSwapchainCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkSwapchainCreateFlagsKHR flags;
VkSurfaceKHR surface;
uint32_t minImageCount;
VkFormat imageFormat;
VkColorSpaceKHR imageColorSpace;
VkExtent2D imageExtent;
uint32_t imageArrayLayers;
VkImageUsageFlags imageUsage;
VkSharingMode imageSharingMode;
uint32_t queueFamilyIndexCount;
const uint32_t* pQueueFamilyIndices;
VkSurfaceTransformFlagBitsKHR preTransform;
VkCompositeAlphaFlagBitsKHR compositeAlpha;
VkPresentModeKHR presentMode;
VkBool32 clipped;
VkSwapchainKHR oldSwapchain;
} VkSwapchainCreateInfoKHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
flags是一个 VkSwapchainCreateFlagBitsKHR 的位掩码,指示交换链创建的参数。 -
surface是交换链将呈现图像的表面。如果创建成功,则交换链将与surface关联。 -
minImageCount是应用程序需要的最小可呈现图像数量。实现将创建至少具有该数量图像的交换链,否则将无法创建交换链。 -
imageFormat是一个 VkFormat 值,指定将创建交换链图像的格式。 -
imageColorSpace是一个 VkColorSpaceKHR 值,指定交换链解释图像数据的方式。 -
imageExtent是交换链图像的大小(以像素为单位)。如果图像范围与vkGetPhysicalDeviceSurfaceCapabilitiesKHR返回的表面的currentExtent不匹配,则行为取决于平台。在某些平台上,
maxImageExtent可能变为(0, 0)是正常的,例如当窗口最小化时。在这种情况下,由于有效使用要求,除非通过 VkSwapchainPresentScalingCreateInfoEXT(如果支持)选择了缩放,否则无法创建交换链。 -
imageArrayLayers是多视图/立体表面中的视图数。对于非立体 3D 应用程序,此值为 1。 -
imageUsage是一个 VkImageUsageFlagBits 的位掩码,描述(获取的)交换链图像的预期用途。 -
imageSharingMode是用于交换链图像的共享模式。 -
queueFamilyIndexCount是当imageSharingMode为VK_SHARING_MODE_CONCURRENT时,有权访问交换链图像的队列族数量。 -
pQueueFamilyIndices是指向当imageSharingMode为VK_SHARING_MODE_CONCURRENT时,有权访问交换链图像的队列族索引数组的指针。 -
preTransform是一个 VkSurfaceTransformFlagBitsKHR 值,描述相对于演示引擎的自然方向,在呈现之前应用于图像内容的变换。如果它与vkGetPhysicalDeviceSurfaceCapabilitiesKHR返回的currentTransform值不匹配,则演示引擎将在呈现操作中转换图像内容。 -
compositeAlpha是一个 VkCompositeAlphaFlagBitsKHR 值,指示在某些窗口系统上将此表面与其他表面组合在一起时使用的 alpha 合成模式。 -
presentMode是交换链将使用的呈现模式。交换链的呈现模式决定了如何内部处理和排队传入的呈现请求。 -
clipped指定是否允许 Vulkan 实现丢弃影响表面不可见区域的渲染操作。-
如果
clipped为VK_TRUE,则与交换链关联的可呈现图像可能不拥有其所有像素。当回读时,可呈现图像中对应于桌面上的另一个窗口遮挡的目标表面区域或受某些其他剪切机制影响的像素将具有未定义的内容。片段着色器可能不会为这些像素执行,因此它们本应具有的任何副作用都不会发生。设置VK_TRUE不能保证会发生任何剪切,但允许在某些平台上使用更有效的呈现方法。 -
如果
clipped为VK_FALSE,则与交换链关联的可呈现图像将拥有它们包含的所有像素。如果应用程序不希望在呈现之前或重新获取后回读可呈现图像的内容,并且它们的片段着色器没有任何需要在可呈现图像中的所有像素上运行的副作用,则应用程序应该将此值设置为
VK_TRUE。
-
-
oldSwapchain是 VK_NULL_HANDLE,或者当前与surface关联的现有非废弃交换链。提供有效的oldSwapchain可能有助于资源重用,并且还允许应用程序仍然呈现已从中获取的任何图像。
当使用不是 VK_NULL_HANDLE 的 oldSwapchain 调用 vkCreateSwapchainKHR 时,oldSwapchain 将被废弃 — 即使新交换链的创建失败。无论 oldSwapchain 是否为 VK_NULL_HANDLE,新的交换链都将在非废弃状态下创建。
当使用非 VK_NULL_HANDLE 的 oldSwapchain 调用 vkCreateSwapchainKHR 时,实现可能会释放 oldSwapchain 中任何未被应用程序获取的图像,即使新交换链的创建失败,这种情况也可能发生。应用程序可以销毁 oldSwapchain 以释放与 oldSwapchain 关联的所有内存。
|
通过多次使用 在 只要从 |
可以在 VkSwapchainCreateInfoKHR::flags 中设置的位,用于指定交换链创建的参数有:
// Provided by VK_KHR_swapchain
typedef enum VkSwapchainCreateFlagBitsKHR {
// Provided by VK_VERSION_1_1 with VK_KHR_swapchain, VK_KHR_device_group with VK_KHR_swapchain
VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = 0x00000001,
// Provided by VK_VERSION_1_1 with VK_KHR_swapchain
VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR = 0x00000002,
// Provided by VK_KHR_swapchain_mutable_format
VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR = 0x00000004,
// Provided by VK_EXT_swapchain_maintenance1
VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT = 0x00000008,
} VkSwapchainCreateFlagBitsKHR;
-
VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR指定从交换链创建的图像(即,VkImageSwapchainCreateInfoKHR 的swapchain成员设置为此交换链的句柄)必须使用VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT。 -
VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR指定从交换链创建的图像是受保护的图像。 -
VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR指定交换链的图像可以用于创建具有与创建交换链时不同的格式的VkImageView。允许的图像视图格式列表通过向 VkSwapchainCreateInfoKHR 的pNext链添加 VkImageFormatListCreateInfo 结构来指定。此外,此标志还指定交换链可以使用不支持交换链创建时所用格式,但至少支持一个允许的图像视图格式的用法标志来创建。 -
VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT指定实现可以延迟分配与每个交换链图像关联的内存,直到其索引首次从 vkAcquireNextImageKHR 或 vkAcquireNextImage2KHR 返回。
// Provided by VK_KHR_swapchain
typedef VkFlags VkSwapchainCreateFlagsKHR;
VkSwapchainCreateFlagsKHR 是一个位掩码类型,用于设置零个或多个 VkSwapchainCreateFlagBitsKHR 的掩码。
如果 VkSwapchainCreateInfoKHR 的 pNext 链包含 VkDeviceGroupSwapchainCreateInfoKHR 结构,则该结构包含一组交换链可以使用的设备组呈现模式。
VkDeviceGroupSwapchainCreateInfoKHR 结构定义如下
// Provided by VK_VERSION_1_1 with VK_KHR_swapchain, VK_KHR_device_group with VK_KHR_swapchain
typedef struct VkDeviceGroupSwapchainCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkDeviceGroupPresentModeFlagsKHR modes;
} VkDeviceGroupSwapchainCreateInfoKHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
modes是交换链可以使用的模式的位域。
如果此结构不存在,则 modes 被视为 VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR。
如果 VkSwapchainCreateInfoKHR 的 pNext 链包含 VkSwapchainDisplayNativeHdrCreateInfoAMD 结构,则该结构包含特定于显示原生 HDR 支持的附加交换链创建参数。
VkSwapchainDisplayNativeHdrCreateInfoAMD 结构定义如下
// Provided by VK_AMD_display_native_hdr
typedef struct VkSwapchainDisplayNativeHdrCreateInfoAMD {
VkStructureType sType;
const void* pNext;
VkBool32 localDimmingEnable;
} VkSwapchainDisplayNativeHdrCreateInfoAMD;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
localDimmingEnable指定是否为交换链启用局部调光。
如果 VkSwapchainCreateInfoKHR 的 pNext 链不包含此结构,则 localDimmingEnable 的默认值为 VK_TRUE,这意味着最初为交换链启用了局部调光。
局部调光 HDR 设置也可以通过调用在交换链的生命周期中更改
// Provided by VK_AMD_display_native_hdr
void vkSetLocalDimmingAMD(
VkDevice device,
VkSwapchainKHR swapChain,
VkBool32 localDimmingEnable);
-
device是与swapChain关联的设备。 -
swapChain是用于启用局部调光的句柄。 -
localDimmingEnable指定是否为交换链启用局部调光。
如果 VkSwapchainCreateInfoKHR 的 pNext 链包含 VkSurfaceFullScreenExclusiveInfoEXT 结构,则该结构指定应用程序首选的全屏演示行为。如果此结构不存在,则 fullScreenExclusive 被视为 VK_FULL_SCREEN_EXCLUSIVE_DEFAULT_EXT。
要在创建交换链时启用表面计数器,请将 VkSwapchainCounterCreateInfoEXT 结构添加到 VkSwapchainCreateInfoKHR 的 pNext 链中。VkSwapchainCounterCreateInfoEXT 定义如下
// Provided by VK_EXT_display_control
typedef struct VkSwapchainCounterCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkSurfaceCounterFlagsEXT surfaceCounters;
} VkSwapchainCounterCreateInfoEXT;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
surfaceCounters是一个 VkSurfaceCounterFlagBitsEXT 的位掩码,指定要为交换链启用的表面计数器。
当演示引擎处理相关交换链的第一个演示命令时,请求的计数器将变为活动状态。要查询活动计数器的值,请使用
// Provided by VK_EXT_display_control
VkResult vkGetSwapchainCounterEXT(
VkDevice device,
VkSwapchainKHR swapchain,
VkSurfaceCounterFlagBitsEXT counter,
uint64_t* pCounterValue);
-
device是与swapchain关联的 VkDevice。 -
swapchain是从中查询计数器值的交换链。 -
counter是一个 VkSurfaceCounterFlagBitsEXT 值,指定要查询的计数器。 -
pCounterValue将返回计数器的当前值。
如果由于交换链已过期而无法使用计数器,则实现可以返回 VK_ERROR_OUT_OF_DATE_KHR。
为了指定此交换链中交换链图像的压缩属性,请将 VkImageCompressionControlEXT 结构添加到 VkSwapchainCreateInfoKHR 结构的 pNext 链中。
应用程序可以在每次呈现的基础上修改交换链使用的呈现模式。但是,应用程序打算与交换链一起使用的所有呈现模式必须在交换链创建时指定。要在创建交换链时指定多个呈现模式,请将 VkSwapchainPresentModesCreateInfoEXT 结构包含在 VkSwapchainCreateInfoKHR 结构的 pNext 链中。
VkSwapchainPresentModesCreateInfoEXT 结构的定义如下:
// Provided by VK_EXT_swapchain_maintenance1
typedef struct VkSwapchainPresentModesCreateInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t presentModeCount;
const VkPresentModeKHR* pPresentModes;
} VkSwapchainPresentModesCreateInfoEXT;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
presentModeCount是提供的呈现模式的数量。 -
pPresentModes是一个包含presentModeCount项的呈现模式列表。
当应用程序呈现的交换链图像的尺寸与目标 surface 的尺寸不同时,根据各自的规范,在不同的平台上可能会出现不同的行为。
-
呈现失败并返回
VK_ERROR_OUT_OF_DATE_KHR。 -
执行缩放并返回
VK_SUCCESS或VK_SUBOPTIMAL_KHR。 -
使用拉伸、居中和/或裁剪的任意组合进行未指定的缩放。
应用程序可以通过将 VkSwapchainPresentScalingCreateInfoEXT 结构包含在 VkSwapchainCreateInfoKHR 结构的 pNext 链中,在创建交换链时定义特定行为。
VkSwapchainPresentScalingCreateInfoEXT 结构的定义如下:
// Provided by VK_EXT_swapchain_maintenance1
typedef struct VkSwapchainPresentScalingCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkPresentScalingFlagsEXT scalingBehavior;
VkPresentGravityFlagsEXT presentGravityX;
VkPresentGravityFlagsEXT presentGravityY;
} VkSwapchainPresentScalingCreateInfoEXT;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
scalingBehavior是0,或者当 surface 和交换链图像的尺寸不同时要使用的缩放方法。 -
当
scalingBehavior不会导致缩放的交换链图像和 surface 之间的一对一像素映射时,presentGravityX是0,或交换链图像像素相对于 surface 移动的 x 轴方向。 -
当
scalingBehavior不会导致缩放的交换链图像和 surface 之间的一对一像素映射时,presentGravityY是0,或交换链图像像素相对于 surface 移动的 y 轴方向。
如果 scalingBehavior 为 0,则呈现尺寸与 surface 尺寸不匹配的交换链图像的结果取决于实现和平台。如果 presentGravityX 或 presentGravityY 为 0,则呈现重力必须与定义 surface 重力的原生平台 surface 所定义的重力相匹配。
要销毁交换链对象,请调用
// Provided by VK_KHR_swapchain
void vkDestroySwapchainKHR(
VkDevice device,
VkSwapchainKHR swapchain,
const VkAllocationCallbacks* pAllocator);
应用程序必须在完成从交换链获取的图像上的所有未完成操作后,才能销毁交换链。 swapchain 和所有关联的 VkImage 句柄将被销毁,并且应用程序必须不再获取或使用它们。每个 VkImage 的内存只有在该图像不再被呈现引擎使用后才会被释放。例如,如果交换链中的一个图像正在窗口中显示,则该图像的内存可能直到窗口被销毁或为该窗口创建另一个交换链后才会被释放。销毁交换链不会使父 VkSurfaceKHR 失效,并且可以使用它创建一个新的交换链。
当销毁与显示表面关联的交换链时,如果最近呈现给显示表面的图像来自正在销毁的交换链,则要么实现必须将通过呈现来自任何与显示表面关联的交换链的图像而修改的任何显示资源恢复到在其中一个交换链上执行第一次呈现之前的状态,要么必须将此类资源保留在其当前状态。
如果 swapchain 具有独占全屏访问权限,则会在销毁交换链之前释放它。
要获取与交换链关联的可呈现图像数组,请调用
// Provided by VK_KHR_swapchain
VkResult vkGetSwapchainImagesKHR(
VkDevice device,
VkSwapchainKHR swapchain,
uint32_t* pSwapchainImageCount,
VkImage* pSwapchainImages);
-
device是与swapchain关联的设备。 -
swapchain是要查询的交换链。 -
pSwapchainImageCount是一个指向整数的指针,该整数与可用的或查询的可呈现图像的数量相关,如下所述。 -
pSwapchainImages可以是NULL或指向VkImage句柄数组的指针。
如果 pSwapchainImages 为 NULL,则 swapchain 的可呈现图像数量将返回到 pSwapchainImageCount 中。否则,pSwapchainImageCount 必须指向一个由应用程序设置为 pSwapchainImages 数组中元素数量的变量,并且在返回时,该变量将被实际写入 pSwapchainImages 的结构数量覆盖。 如果 pSwapchainImageCount 的值小于 swapchain 的可呈现图像数量,则最多将写入 pSwapchainImageCount 个结构,并且将返回 VK_INCOMPLETE 而不是 VK_SUCCESS,以指示并非所有可用的可呈现图像都被返回。
|
通过了解交换链中使用的所有可呈现图像,应用程序可以在进入其主渲染循环之前创建引用这些图像的命令缓冲区。但是,在它们的索引从 vkAcquireNextImageKHR 返回至少一次之前,不允许命令缓冲区引用使用 |
由 vkGetSwapchainImagesKHR 返回的图像在传递给应用程序之前,会完全由内存支持,就像它们完全且连续地绑定到单个 VkDeviceMemory 对象一样,除非交换链是使用 VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT 标志创建的。所有可呈现图像最初都处于 VK_IMAGE_LAYOUT_UNDEFINED 布局中,因此在使用可呈现图像之前,应用程序必须将其转换为预期用途的有效布局。
此外,可呈现图像的生命周期由实现控制,因此应用程序必须不销毁可呈现图像。有关可呈现图像的生命周期的更多详细信息,请参阅 vkDestroySwapchainKHR。
也可以使用 vkCreateImage 和 VkImageSwapchainCreateInfoKHR 创建图像,并使用 vkBindImageMemory2 和 VkBindImageMemorySwapchainInfoKHR 绑定到交换链内存。这些图像可以在任何使用交换链图像的地方使用,并且在具有多个物理设备的逻辑设备中创建交换链内存的对等内存绑定很有用。这些图像和绑定对呈现的内存没有任何影响。与从 vkGetSwapchainImagesKHR 检索的图像不同,这些图像必须使用 vkDestroyImage 销毁。
要获取可用的可呈现图像以使用并检索该图像的索引,请调用
// Provided by VK_KHR_swapchain
VkResult vkAcquireNextImageKHR(
VkDevice device,
VkSwapchainKHR swapchain,
uint64_t timeout,
VkSemaphore semaphore,
VkFence fence,
uint32_t* pImageIndex);
-
device是与swapchain关联的设备。 -
swapchain是从中获取图像的未停用的交换链。 -
timeout指定如果没有可用图像,该函数等待多长时间,以纳秒为单位。 -
semaphore是 VK_NULL_HANDLE 或要发出信号的信号量。 -
fence是 VK_NULL_HANDLE 或要发出信号的栅栏。 -
pImageIndex是一个指向uint32_t的指针,其中返回要使用的下一个图像的索引(即,vkGetSwapchainImagesKHR返回的图像数组的索引)。
如果使用 VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT 标志创建了 swapchain,则在调用返回到应用程序之前,pImageIndex 中返回的索引对应的图像将完全由内存支持,就像它完全且连续地绑定到单个 VkDeviceMemory 对象一样。
如果成功获取图像,vkAcquireNextImageKHR 必须 返回 VK_SUCCESS 或 VK_SUBOPTIMAL_KHR。如果交换链不再完全匹配表面属性,但仍然可以用于显示,则实现可以返回 VK_SUBOPTIMAL_KHR。
成功时,vkAcquireNextImageKHR 从 swapchain 获取应用程序可以使用的可显示图像,并将 pImageIndex 设置为该图像在交换链中的索引。显示引擎在获取图像时可能尚未完成对图像的读取,因此应用程序必须使用 semaphore 和/或 fence 来确保在显示引擎完成读取之前,图像布局和内容不会被修改。一旦 vkAcquireNextImageKHR 成功获取图像,则由 semaphore 引用的信号量信号操作(如果不是 VK_NULL_HANDLE)以及由 fence 引用的栅栏信号操作(如果不是 VK_NULL_HANDLE)将被提交执行。如果 vkAcquireNextImageKHR 未成功获取图像,则 semaphore 和 fence 不会受到影响。图像的获取顺序取决于实现,并且可能与图像的显示顺序不同。
如果 timeout 为零,则 vkAcquireNextImageKHR 不会等待,并且会成功获取图像,或者在没有可用图像时失败并返回 VK_NOT_READY。
如果在获取图像之前指定的超时时间到期,则 vkAcquireNextImageKHR 返回 VK_TIMEOUT。如果 timeout 为 UINT64_MAX,则超时时间被视为无限,并且 vkAcquireNextImageKHR 将阻塞,直到获取图像或发生错误为止。
令 S 为 swapchain 中的图像数量。如果 swapchain 是使用 VkSwapchainPresentModesCreateInfoEXT 创建的,则令 M 为在 VkSurfacePresentModeEXT 中使用 VkSwapchainPresentModesCreateInfoEXT::pPresentModes 中的每个显示模式查询时 VkSurfaceCapabilitiesKHR::minImageCount 中值的最大值。否则,令 M 为没有 VkSurfacePresentModeEXT 作为查询输入时 VkSurfaceCapabilitiesKHR::minImageCount 的值。
如果应用程序当前已获取的图像数量大于 S-M,则不应调用 vkAcquireNextImageKHR。如果调用 vkAcquireNextImageKHR 时应用程序当前已获取的图像数量小于或等于 S-M,则 vkAcquireNextImageKHR 必须在有限的时间内返回允许的 VkResult 代码。
|
在有限时间内返回结果可保证实现不会因应用程序死锁或在 API 使用正确的情况下无限期地暂停执行。一次获取太多图像可能会无限期地阻塞,这在使用 |
如果交换链图像不再匹配本地表面属性,则必须返回 VK_SUBOPTIMAL_KHR 或 VK_ERROR_OUT_OF_DATE_KHR。如果返回 VK_ERROR_OUT_OF_DATE_KHR,则不会获取图像,并且尝试将先前获取的图像呈现到交换链也将失败,并返回 VK_ERROR_OUT_OF_DATE_KHR。如果返回 VK_ERROR_OUT_OF_DATE_KHR,则应用程序需要为表面创建一个新的交换链才能继续显示。
|
例如,如果平台表面已调整大小,但平台能够将显示的图像缩放到新尺寸以生成有效的表面更新,则可能会发生 |
如果在超时到期之前发生设备丢失(请参阅设备丢失),则 vkAcquireNextImageKHR 必须在有限时间内返回允许的成功代码之一或 VK_ERROR_DEVICE_LOST。
如果 semaphore 不是 VK_NULL_HANDLE,则信号量必须处于未发出信号状态,并且没有未决的信号或等待操作。当应用程序可以使用图像时,它将变为已发出信号状态。
|
使用 |
如果 fence 不等于 VK_NULL_HANDLE,则栅栏必须处于未发出信号状态,并且没有未决的信号操作。当应用程序可以使用图像时,它将变为已发出信号状态。
|
应用程序不应依赖 |
应用程序必须等待直到 semaphore 或 fence 发出信号后才能访问图像的数据。
|
当可显示图像将由某个阶段 S 访问时,用于确保正确同步的建议用法是
|
成功返回后,pImageIndex 指示的图像及其数据与呈现时相比将保持不变。
|
在资源共享中定义的,使用 |
vkAcquireNextImageKHR 的可能返回值取决于提供的 timeout 值。
-
如果图像变为可用,则返回
VK_SUCCESS。 -
如果表面不再可用,则返回
VK_ERROR_SURFACE_LOST_KHR。 -
如果
timeout为零且没有可用的图像,则返回VK_NOT_READY。 -
如果
timeout大于零且小于UINT64_MAX,并且在允许的时间内没有可用的图像,则返回VK_TIMEOUT。 -
如果图像变为可用,并且交换链不再与表面属性完全匹配,但仍然可以成功地呈现到表面,则返回
VK_SUBOPTIMAL_KHR。
|
例如,如果平台表面已调整大小,但平台能够缩放呈现的图像以产生有效的表面更新,则可能会发生这种情况。应用程序可以决定是继续无限期地使用当前交换链或在此状态下临时使用,还是重新创建交换链以更好地匹配平台表面属性。 |
-
如果表面的更改方式导致其不再与交换链兼容,并且使用该交换链的后续呈现请求将失败,则返回
VK_ERROR_OUT_OF_DATE_KHR。如果应用程序希望继续呈现到表面,则必须查询新的表面属性并重新创建其交换链。
如果原生表面和呈现图像的大小不再匹配,则除非在VkSwapchainPresentScalingCreateInfoEXT::scalingBehavior 中使用非零值创建交换链,否则呈现可能会失败。如果呈现成功,则呈现图像到原生表面的映射由提供的VkSwapchainPresentScalingCreateInfoEXT结构定义。否则,它是实现定义的。检测表面大小变化并做出适当的反应是应用程序的责任。如果由于表面和呈现图像大小不匹配而导致呈现失败,则会返回 VK_ERROR_OUT_OF_DATE_KHR 错误。
|
例如,考虑一个 4x3 的窗口/表面,它被调整为 3x4(比宽度更高)。在某些窗口系统中,先前可见且仍然可见的窗口/表面部分(3x3 部分)将包含与之前相同的内容,而窗口的其余部分将具有未定义的内容。其他窗口系统可能会压缩/拉伸图像以填充新的窗口大小,而没有任何未定义的内容,或者应用一些其他映射。 |
要获取可用的可呈现图像以使用并检索该图像的索引,请调用
// Provided by VK_VERSION_1_1 with VK_KHR_swapchain, VK_KHR_device_group with VK_KHR_swapchain
VkResult vkAcquireNextImage2KHR(
VkDevice device,
const VkAcquireNextImageInfoKHR* pAcquireInfo,
uint32_t* pImageIndex);
-
device是与swapchain关联的设备。 -
pAcquireInfo是指向 VkAcquireNextImageInfoKHR 结构的指针,其中包含获取的参数。 -
pImageIndex是指向一个uint32_t值的指针,该值指定要使用的下一个图像的索引。
如果 swapchain 是使用 VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT 标志创建的,则在调用返回给应用程序之前,pImageIndex 中返回的索引对应的图像将完全由内存支持。
VkAcquireNextImageInfoKHR 结构的定义如下:
// Provided by VK_VERSION_1_1 with VK_KHR_swapchain, VK_KHR_device_group with VK_KHR_swapchain
typedef struct VkAcquireNextImageInfoKHR {
VkStructureType sType;
const void* pNext;
VkSwapchainKHR swapchain;
uint64_t timeout;
VkSemaphore semaphore;
VkFence fence;
uint32_t deviceMask;
} VkAcquireNextImageInfoKHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
swapchain是从中获取图像的非退休交换链。 -
timeout指定如果没有可用图像,该函数等待多长时间,以纳秒为单位。 -
semaphore是 VK_NULL_HANDLE 或要发出信号的信号量。 -
fence是 VK_NULL_HANDLE 或要发出信号的栅栏。 -
deviceMask是一个物理设备掩码,当信号量或栅栏被触发时,交换链图像将准备好供这些物理设备使用。
如果使用 vkAcquireNextImageKHR,则设备掩码被认为包括逻辑设备中的所有物理设备。
|
vkAcquireNextImage2KHR 最多触发一个信号量,即使应用程序请求等待多个物理设备通过 |
在将所有渲染命令入队并将图像转换为正确的布局后,要将图像入队以进行显示,请调用
// Provided by VK_KHR_swapchain
VkResult vkQueuePresentKHR(
VkQueue queue,
const VkPresentInfoKHR* pPresentInfo);
-
queue是一个能够在与图像的交换链相同的设备上,向目标表面的平台进行显示的队列。 -
pPresentInfo是指向 VkPresentInfoKHR 结构的指针,该结构指定了显示的参数。
|
应用程序不需要按照获取图像的顺序显示图像——应用程序可以任意显示当前已获取的任何图像。 |
|
表面坐标系的本机方向的原点未在 Vulkan 规范中指定;它取决于平台。对于大多数平台,默认情况下原点位于左上角,这意味着所呈现的 VkImage 上坐标 (0,0) 处的像素将出现在平台表面的左上角像素处(假设 |
当 vkQueuePresentKHR 返回 VK_ERROR_OUT_OF_DATE_KHR 和 VK_SUBOPTIMAL_KHR 结果码时,其含义与 vkAcquireNextImageKHR 返回时相同。如果 pPresentInfo 的任何 swapchain 成员是使用 VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT 创建的,如果该交换链没有独占全屏访问权限,则将返回 VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT,这可能是因为应用程序无法控制的特定于实现的原因。如果呈现多个交换链,则结果码将按以下顺序应用规则确定
-
如果设备丢失,则返回
VK_ERROR_DEVICE_LOST。 -
如果任何目标表面不再可用,则返回错误
VK_ERROR_SURFACE_LOST_KHR。 -
如果任何呈现会单独发出并返回
VK_ERROR_OUT_OF_DATE_KHR,则返回VK_ERROR_OUT_OF_DATE_KHR。 -
如果任何呈现会单独发出并返回
VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT,则返回VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT。 -
如果任何呈现会单独发出并返回
VK_SUBOPTIMAL_KHR,则返回VK_SUBOPTIMAL_KHR。 -
否则,返回
VK_SUCCESS。
在 vkQueuePresentKHR 执行之前,对 pPresentInfo 的 pImageIndices 和 pSwapchains 成员引用的图像的后备内存的任何写入,都会自动对显示引擎执行的读取访问可见。图像的这种自动可见性操作发生在信号量信号操作之后,并且发生在显示引擎访问图像之前。
显示是一个只读操作,不会影响可显示图像的内容。在重新获取图像并将其从 VK_IMAGE_LAYOUT_PRESENT_SRC_KHR 布局转换出来后,其内容将与将图像转换为显示源布局并进行显示之前相同。但是,如果使用 Vulkan 以外的机制来修改与交换链关联的平台窗口,则交换链中所有可显示图像的内容都将变为未定义。
对 vkQueuePresentKHR 的调用可能会阻塞,但必须在有限的时间内返回。显示的处理按入队顺序与其他队列操作一起发生,但必须使用信号量来确保指定队列中先前的渲染和其他命令在显示开始之前完成。显示命令本身不会延迟队列中后续命令的处理。但是,发送到特定队列的显示请求始终按顺序执行。确切的显示时间由所使用的显示引擎和本机平台的语义控制。
如果将图像显示到从显示表面创建的交换链,则如果需要,将更新关联显示的模式,以匹配创建显示表面时指定的模式。模式切换和指定图像的显示将作为一个原子操作执行。
将图像入队进行显示定义了一组队列操作,包括等待信号量并将显示请求提交给显示引擎。但是,这组队列操作的范围不包括显示引擎对图像的实际处理。
如果 vkQueuePresentKHR 未能将相应的队列操作集入队,则它可能会返回 VK_ERROR_OUT_OF_HOST_MEMORY 或 VK_ERROR_OUT_OF_DEVICE_MEMORY。如果返回这些错误,则实现必须确保引用的任何资源或同步原语的状态和内容不受调用或其失败的影响。
如果 vkQueuePresentKHR 的失败方式导致实现无法做出该保证,则实现必须返回 VK_ERROR_DEVICE_LOST。
但是,如果显示引擎由于错误 VK_ERROR_OUT_OF_DATE_KHR、VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT 或 VK_ERROR_SURFACE_LOST_KHR 而拒绝显示请求,则队列操作集仍被视为已入队,因此,当相应的队列操作完成时,VkPresentInfoKHR 中指定的任何信号量等待操作都将执行。
vkQueuePresentKHR 释放对 imageIndices 引用的图像的获取。在 资源共享 中定义的那样,vkQueuePresentKHR 执行所在的队列对应的队列族必须拥有所显示图像的所有权。vkQueuePresentKHR 不会改变队列族的所有权,但是所显示的图像必须在通过 vkAcquireNextImageKHR 重新获取之前不再使用。
|
只要交换链没有进入导致 vkQueuePresentKHR 返回 |
VkPresentInfoKHR 结构定义如下:
// Provided by VK_KHR_swapchain
typedef struct VkPresentInfoKHR {
VkStructureType sType;
const void* pNext;
uint32_t waitSemaphoreCount;
const VkSemaphore* pWaitSemaphores;
uint32_t swapchainCount;
const VkSwapchainKHR* pSwapchains;
const uint32_t* pImageIndices;
VkResult* pResults;
} VkPresentInfoKHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
waitSemaphoreCount是发出呈现请求之前要等待的信号量的数量。该数量可能为零。 -
pWaitSemaphores为NULL或指向包含waitSemaphoreCount个条目的 VkSemaphore 对象数组的指针,并指定在发出呈现请求之前要等待的信号量。 -
swapchainCount是此命令要呈现到的交换链的数量。 -
pSwapchains是指向包含swapchainCount个条目的 VkSwapchainKHR 对象数组的指针。 -
pImageIndices是指向每个交换链的可呈现图像数组的索引数组的指针,其中包含swapchainCount个条目。此数组中的每个条目都标识要在pSwapchains数组中相应条目上呈现的图像。 -
pResults是指向包含swapchainCount个条目的 VkResult 类型元素的数组的指针。不需要每个交换链结果的应用程序可以对pResults使用NULL。如果非NULL,则pResults中的每个条目都将设置为与pSwapchains中相同索引对应的交换链的呈现 VkResult。
在应用程序可以呈现图像之前,图像的布局必须转换为 VK_IMAGE_LAYOUT_PRESENT_SRC_KHR 布局,或者对于共享的可呈现图像,转换为 VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR 布局。
|
当将图像转换为 |
当启用 VK_KHR_incremental_present 扩展时,可以指定额外的字段,允许应用程序指定交换链的可呈现图像中只有某些矩形区域发生了更改。这是一个优化提示,演示引擎可能会使用它来仅更新实际更改的表面区域。应用程序仍然必须确保所呈现图像的所有像素都包含所需的值,以防演示引擎忽略此提示。应用程序可以通过将 VkPresentRegionsKHR 结构添加到 VkPresentInfoKHR 结构的 pNext 链中来提供此提示。
VkPresentRegionsKHR 结构定义如下:
// Provided by VK_KHR_incremental_present
typedef struct VkPresentRegionsKHR {
VkStructureType sType;
const void* pNext;
uint32_t swapchainCount;
const VkPresentRegionKHR* pRegions;
} VkPresentRegionsKHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
swapchainCount是此命令要呈现到的交换链的数量。 -
pRegions可以是NULL或指向包含swapchainCount个VkPresentRegionKHR元素的数组的指针。如果不是NULL,则pRegions的每个元素都包含自上次呈现到VkPresentInfoKHR::pSwapchains数组中相应条目的交换链以来发生更改的区域。
对于给定的图像和交换链,要呈现的区域由 VkPresentRegionKHR 结构指定,其定义如下:
// Provided by VK_KHR_incremental_present
typedef struct VkPresentRegionKHR {
uint32_t rectangleCount;
const VkRectLayerKHR* pRectangles;
} VkPresentRegionKHR;
-
rectangleCount是pRectangles中的矩形数量,如果整个图像已更改且应呈现,则为零。 -
pRectangles可以是NULL或指向VkRectLayerKHR结构数组的指针。VkRectLayerKHR结构是可呈现图像的一部分的帧缓冲坐标加上层,该部分已更改并且必须呈现。如果不是NULL,则pRectangles中的每个条目都是自上次将图像呈现给给定交换链以来已更改的给定图像的矩形。矩形必须相对于 VkSurfaceCapabilitiesKHR::currentTransform指定,而不管交换链的preTransform如何。演示引擎会将preTransform转换应用于矩形,以及它应用于图像内容的任何进一步转换。
VkRectLayerKHR 结构定义如下:
// Provided by VK_KHR_incremental_present
typedef struct VkRectLayerKHR {
VkOffset2D offset;
VkExtent2D extent;
uint32_t layer;
} VkRectLayerKHR;
-
offset是矩形的起始位置,以像素为单位。 -
extent是矩形的大小,以像素为单位。 -
layer是图像的层。对于只有一层的图像,layer的值必须为 0。
某些平台允许表面大小更改,然后缩放图像的像素以适应表面。VkRectLayerKHR 指定交换链的图像像素,这些像素在交换链的生命周期内将保持不变。
当启用 VK_KHR_display_swapchain 扩展时,可以通过将 VkPresentInfoKHR::pNext 设置为指向 VkDisplayPresentInfoKHR 结构,在将图像呈现到交换链时指定额外的字段。
VkDisplayPresentInfoKHR 结构定义如下:
// Provided by VK_KHR_display_swapchain
typedef struct VkDisplayPresentInfoKHR {
VkStructureType sType;
const void* pNext;
VkRect2D srcRect;
VkRect2D dstRect;
VkBool32 persistent;
} VkDisplayPresentInfoKHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
srcRect是要呈现的像素的矩形区域。它必须是要呈现的图像的子集。如果未指定VkDisplayPresentInfoKHR,则此区域将假定为整个可呈现图像。 -
dstRect是交换链的显示模式的可见区域内的矩形区域。如果未指定VkDisplayPresentInfoKHR,则此区域将假定为交换链模式的整个可见区域。如果指定的矩形是显示模式的可见区域的子集,则交换链平面下方的显示平面中的内容将在矩形外部可见。如果没有交换链下方的平面,则指定矩形外部的区域将为黑色。如果指定矩形的部分位于显示器的可见区域之外,则仅映射到矩形这些部分的像素将被丢弃。 -
persistent:如果此值为VK_TRUE,则显示引擎将在支持它的显示器上启用缓冲模式。这允许显示引擎停止向显示器发送内容,直到呈现新图像。显示器将改为维护上次呈现的图像的副本。这可以减少功耗,但可能会增加呈现延迟。如果未指定VkDisplayPresentInfoKHR,则不会使用持久模式。
如果 srcRect 和 dstRect 的范围不相等,则呈现的像素将相应地缩放。
如果 VkPresentInfoKHR 的 pNext 链包含 VkDeviceGroupPresentInfoKHR 结构,则该结构包含设备掩码数组和设备组呈现模式。
VkDeviceGroupPresentInfoKHR 结构定义如下:
// Provided by VK_VERSION_1_1 with VK_KHR_swapchain, VK_KHR_device_group with VK_KHR_swapchain
typedef struct VkDeviceGroupPresentInfoKHR {
VkStructureType sType;
const void* pNext;
uint32_t swapchainCount;
const uint32_t* pDeviceMasks;
VkDeviceGroupPresentModeFlagBitsKHR mode;
} VkDeviceGroupPresentInfoKHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
swapchainCount为零或pDeviceMasks中的元素数量。 -
pDeviceMasks是指向设备掩码数组的指针,数组中每个元素对应 VkPresentInfoKHR::pSwapchains的一个元素。 -
mode是一个 VkDeviceGroupPresentModeFlagBitsKHR 值,指定本次呈现将使用的设备组呈现模式。
如果 mode 为 VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR,则 pDeviceMasks 的每个元素选择要呈现的交换链图像的哪个实例。 pDeviceMasks 的每个元素必须只有一个位被设置,并且对应的物理设备必须具有由 VkDeviceGroupPresentCapabilitiesKHR 报告的呈现引擎。
如果 mode 为 VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR,则 pDeviceMasks 的每个元素选择要呈现的交换链图像的哪个实例。 pDeviceMasks 的每个元素必须只有一个位被设置,并且逻辑设备中的某个物理设备必须在其 VkDeviceGroupPresentCapabilitiesKHR::presentMask 中包含该位。
如果 mode 为 VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR,则 pDeviceMasks 的每个元素选择要逐分量求和的交换链图像的哪些实例,并将这些图像的和呈现出来。如果任何分量中的和超出可表示范围,则该分量的值是未定义的。 pDeviceMasks 的每个元素必须有一个值,该值的所有设置位都设置在 VkDeviceGroupPresentCapabilitiesKHR::presentMask 的一个元素中。
如果 mode 为 VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR,则 pDeviceMasks 的每个元素选择要呈现的交换链图像的一个或多个实例。 对于 pDeviceMasks 的每个元素中设置的每个位,对应的物理设备必须具有由 VkDeviceGroupPresentCapabilitiesKHR 报告的呈现引擎。
如果未提供 VkDeviceGroupPresentInfoKHR 或 swapchainCount 为零,则认为掩码为 1。如果未提供 VkDeviceGroupPresentInfoKHR,则认为 mode 为 VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR。
启用 VK_GOOGLE_display_timing 扩展时,可以指定其他字段,允许应用程序指定图像应显示的最早时间。这允许应用程序避免因图像显示早于计划而导致的卡顿。这种卡顿可能发生在固定刷新率和可变刷新率的显示器上,因为当几何图形的位置与图像显示的时间不正确时就会发生卡顿。应用程序可以通过将 VkPresentTimesInfoGOOGLE 结构添加到 VkPresentInfoKHR 结构的 pNext 链中,来指示呈现引擎图像不应早于指定时间显示。
VkPresentTimesInfoGOOGLE 结构定义为
// Provided by VK_GOOGLE_display_timing
typedef struct VkPresentTimesInfoGOOGLE {
VkStructureType sType;
const void* pNext;
uint32_t swapchainCount;
const VkPresentTimeGOOGLE* pTimes;
} VkPresentTimesInfoGOOGLE;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
swapchainCount是此命令要呈现到的交换链的数量。 -
pTimes为NULL或指向具有swapchainCount个条目的VkPresentTimeGOOGLE元素数组的指针。如果不是NULL,则pTimes的每个元素都包含呈现与VkPresentInfoKHR::pImageIndices数组中的条目对应的图像的最早时间。
VkPresentTimeGOOGLE 结构定义如下:
// Provided by VK_GOOGLE_display_timing
typedef struct VkPresentTimeGOOGLE {
uint32_t presentID;
uint64_t desiredPresentTime;
} VkPresentTimeGOOGLE;
-
presentID是应用程序提供的标识值,可以 与 vkGetPastPresentationTimingGOOGLE 的结果一起使用,以便唯一标识此 present。为了对应用程序有用,它在对应用程序有意义的一段时间内应该是唯一的。 -
desiredPresentTime指定给定的图像应该不早于此时间显示给用户。desiredPresentTime是以纳秒为单位的时间,相对于单调递增的时钟(例如,Android 和 Linux 上的CLOCK_MONOTONIC(请参阅 clock_gettime(2)))。值为零表示演示引擎可以在任何时间显示图像。当应用程序希望提供presentID,但不需要特定的desiredPresentTime时,这很有用。
VkPresentIdKHR 结构定义如下:
// Provided by VK_KHR_present_id
typedef struct VkPresentIdKHR {
VkStructureType sType;
const void* pNext;
uint32_t swapchainCount;
const uint64_t* pPresentIds;
} VkPresentIdKHR;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
swapchainCount是传递给vkQueuePresentKHR命令的交换链的数量。 -
pPresentIds为NULL或指向包含swapchainCount个条目的uint64_t数组的指针。如果不是NULL,则pPresentIds中的每个非零值指定与 vkQueuePresentKHR 调用中具有相同索引的交换链的演示相关联的 present id。
为了使应用程序能够引用通过调用 vkQueuePresentKHR 排队的特定演示事件,需要将标识符与它们关联。当启用 presentId 功能时,应用程序可以在 VkPresentInfoKHR 结构的 pNext 链中包含 VkPresentIdKHR 结构以提供标识符。
每个 VkSwapchainKHR 都有一个与之关联的 presentId。当创建 VkSwapchainKHR 时,此值最初为零。
当在 VkPresentInfoKHR 结构的 pNext 链中包含具有非 NULL pPresentIds 的 VkPresentIdKHR 结构时,每个 pSwapchains 条目在 pPresentIds 数组中具有一个与 pSwapchains 数组中交换链相同索引的 presentId 相关联。如果此 presentId 为非零值,则应用程序稍后可以使用此值来引用该图像演示。值为零表示此演示没有关联的 presentId。非零 presentId 必须大于应用程序先前为同一交换链传递的任何非零 presentId。
图像向用户演示和 presentId 值的更新之间没有精确的时间关系要求,但实现应该使其尽可能接近新图像的第一个像素向用户演示的时间。
当启用 presentWait 功能时,应用程序可以通过以下方式等待图像呈现给用户:首先通过将 VkPresentIdKHR 结构添加到 VkPresentInfoKHR 结构的 pNext 链中,为目标演示指定 presentId,然后通过调用等待演示完成:
// Provided by VK_KHR_present_wait
VkResult vkWaitForPresentKHR(
VkDevice device,
VkSwapchainKHR swapchain,
uint64_t presentId,
uint64_t timeout);
-
device是与swapchain关联的设备。 -
swapchain是在其上排队等待演示的非退役交换链。 -
presentId是要等待的演示 presentId。 -
timeout是以纳秒为单位的超时时间。timeout会调整为实现相关的超时精度允许的最接近的值,该值可能比一纳秒长得多,并且可能比请求的时间段长。
vkWaitForPresentKHR 等待与 swapchain 关联的 presentId 的值增加,使其至少等于 presentId。
对于 VK_PRESENT_MODE_MAILBOX_KHR (或其他可以在演示队列中替换图像的演示模式),与此类图像关联的任何等待必须在与替换图像关联的等待发出信号的时间之前发出信号。
当演示完成后,与相关 pSwapchains 条目关联的 presentId 的值将增加,使其至少等于 VkPresentIdKHR 结构中提供的值。
图像向用户演示和 presentId 值的更新之间没有精确的时间关系要求,但实现应该使其尽可能接近下一个要向用户演示的图像的第一个像素的演示时间。
对 vkWaitForPresentKHR 的调用将阻塞,直到与 swapchain 关联的 presentId 大于或等于 presentId,或者经过 timeout 纳秒。当交换链变为 OUT_OF_DATE 时,该调用将返回 VK_SUCCESS(如果图像已传递给演示引擎并且可能已呈现给用户),或者将以状态 VK_ERROR_OUT_OF_DATE_KHR 提前返回(如果图像未呈现给用户)。
作为外部同步对象的正常规则的例外,传递给 vkWaitForPresentKHR 的 swapchain **可以**被其他线程同时用于调用除 vkDestroySwapchainKHR 之外的函数。对与此扩展相关的交换链数据的访问**必须**在实现中是原子的。
当启用 VK_GGP_frame_token 扩展时,通过将 VkPresentFrameTokenGGP 结构添加到 VkPresentInfoKHR 结构的 pNext 链中,在向交换链呈现图像时**可以**指定 Google Games Platform 帧令牌。
VkPresentFrameTokenGGP 结构定义为
// Provided by VK_GGP_frame_token
typedef struct VkPresentFrameTokenGGP {
VkStructureType sType;
const void* pNext;
GgpFrameToken frameToken;
} VkPresentFrameTokenGGP;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
frameToken是 Google Games Platform 帧令牌。
VkSwapchainPresentModeInfoEXT 结构定义为
// Provided by VK_EXT_swapchain_maintenance1
typedef struct VkSwapchainPresentModeInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t swapchainCount;
const VkPresentModeKHR* pPresentModes;
} VkSwapchainPresentModeInfoEXT;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
swapchainCount是此命令要呈现到的交换链的数量。 -
pPresentModes是一个包含swapchainCount个条目的呈现模式列表。
如果 VkPresentInfoKHR 的 pNext 链包含 VkSwapchainPresentModeInfoEXT 结构,则该结构定义当前和后续呈现操作使用的呈现模式。
当应用程序使用 VkSwapchainPresentModeInfoEXT 更改呈现模式时,已排队等待呈现的图像将继续按照之前的呈现模式进行呈现。当前正在排队等待呈现的图像和后续图像将按照新的呈现模式进行呈现。两种模式之间转换期间的行为定义如下。
-
从
VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR转换为VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR:呈现引擎根据VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR的行为更新共享可呈现图像。 -
从
VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR转换为VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR:呈现引擎**可能**会更新共享可呈现图像,或者将其延迟到其常规刷新周期,根据VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR的行为。 -
在
VK_PRESENT_MODE_FIFO_KHR和VK_PRESENT_MODE_FIFO_RELAXED_KHR之间转换:图像继续附加到同一个 FIFO 队列,并且关于等待垂直消隐期的行为将遵循当前和后续图像的新模式。 -
从
VK_PRESENT_MODE_IMMEDIATE_KHR转换为VK_PRESENT_MODE_FIFO_KHR或VK_PRESENT_MODE_FIFO_RELAXED_KHR或VK_PRESENT_MODE_FIFO_LATEST_READY_EXT:由于VK_PRESENT_MODE_IMMEDIATE_KHR模式中的所有先前的呈现请求都立即应用,因此在此模式中没有未完成的呈现操作,当前和后续图像将附加到 FIFO 队列并按照新模式进行呈现。 -
从
VK_PRESENT_MODE_MAILBOX_KHR转换为VK_PRESENT_MODE_FIFO_KHR或VK_PRESENT_MODE_FIFO_RELAXED_KHR或VK_PRESENT_MODE_FIFO_LATEST_READY_EXT:FIFO 模式中的呈现需要等待下一个垂直消隐期,其中VK_PRESENT_MODE_MAILBOX_KHR允许将挂起的呈现操作替换为新的呈现操作。在这种情况下,当前呈现操作将替换挂起的呈现操作,并根据新模式应用。 -
从
VK_PRESENT_MODE_FIFO_KHR或VK_PRESENT_MODE_FIFO_RELAXED_KHR或VK_PRESENT_MODE_FIFO_LATEST_READY_EXT转换为VK_PRESENT_MODE_IMMEDIATE_KHR或VK_PRESENT_MODE_MAILBOX_KHR:如果 FIFO 队列为空,则按照新模式的行为进行呈现。如果 FIFO 队列中有呈现操作,则一旦基于相应的垂直消隐期执行了最后一次呈现操作,则当前和后续更新将按照新模式应用。 -
在
VK_PRESENT_MODE_FIFO_KHR或VK_PRESENT_MODE_FIFO_RELAXED_KHR和VK_PRESENT_MODE_FIFO_LATEST_READY_EXT之间转换:图像继续附加到同一个 FIFO 队列,并且关于等待垂直消隐期和出队请求的行为将遵循当前和后续图像的新模式。 -
如果在任何其他呈现模式之间可能进行转换,则转换期间的行为是实现定义的。
VkSwapchainPresentFenceInfoEXT 结构定义为
// Provided by VK_EXT_swapchain_maintenance1
typedef struct VkSwapchainPresentFenceInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t swapchainCount;
const VkFence* pFences;
} VkSwapchainPresentFenceInfoEXT;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
swapchainCount是此命令要呈现到的交换链的数量。 -
pFences是一个包含swapchainCount个条目的栅栏列表。每个条目**必须**是 VK_NULL_HANDLE 或一个栅栏的句柄,该栅栏在相关操作在关联的交换链上完成后发出信号。
通过将图像排队等待呈现以及呈现引擎执行的操作定义的一组队列操作访问与呈现操作关联的对象的有效负载。关联的对象包括
-
交换链图像、其隐式绑定的内存,以及绑定到该内存的任何其他资源。
-
在将图像排队以进行呈现时指定的等待信号量。
应用程序可以提供一个栅栏,当所有此类队列操作完成并且呈现引擎已获取作为呈现操作一部分访问的任何对象的有效负载的引用时,实现将发出该栅栏的信号。对于呈现引擎使用等效的引用传递导入的所有二进制等待信号量,如导入信号量有效负载中所述,此栅栏必须在呈现引擎重置所有此类信号量有效负载后才发出信号。
当至少一个关联的栅栏发出信号时,应用程序可以销毁与给定呈现操作关联的等待信号量,并且当与引用该交换链的所有过去的呈现请求关联的栅栏发出信号时,可以销毁交换链。
在同一个 VkQueue 上对同一个交换链进行的呈现操作关联的栅栏必须按照呈现操作的顺序发出信号。
要为呈现操作中的每个交换链指定栅栏,请在 VkPresentInfoKHR 结构的 pNext 链中包含 VkSwapchainPresentFenceInfoEXT 结构。
要释放先前通过 vkAcquireNextImage2KHR 或 vkAcquireNextImageKHR 获取的图像,请调用
// Provided by VK_EXT_swapchain_maintenance1
VkResult vkReleaseSwapchainImagesEXT(
VkDevice device,
const VkReleaseSwapchainImagesInfoEXT* pReleaseInfo);
-
device是与 VkReleaseSwapchainImagesInfoEXT::swapchain关联的设备。 -
pReleaseInfo是指向 VkReleaseSwapchainImagesInfoEXT 结构的指针,该结构包含释放的参数。
只能释放设备未使用的图像。
释放图像是一种只读操作,不会影响已释放图像的内容。重新获取图像后,图像内容及其布局将与释放前相同。但是,如果使用 Vulkan 以外的机制来修改与交换链关联的平台窗口,则交换链中所有可呈现图像的内容将变为未定义。
|
此功能在交换链重建期间非常有用,其中可以释放旧交换链中获取的图像,而不是呈现它们。 |
VkReleaseSwapchainImagesInfoEXT 结构的定义如下
// Provided by VK_EXT_swapchain_maintenance1
typedef struct VkReleaseSwapchainImagesInfoEXT {
VkStructureType sType;
const void* pNext;
VkSwapchainKHR swapchain;
uint32_t imageIndexCount;
const uint32_t* pImageIndices;
} VkReleaseSwapchainImagesInfoEXT;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
swapchain是要释放图像的交换链。 -
imageIndexCount是要释放的图像索引的数量。 -
pImageIndices是指向swapchain的可呈现图像数组的索引数组的指针,其中包含imageIndexCount个条目。
HDR 元数据
本节介绍如何改进内容色彩的再现,以更好地再现最初用于优化内容的显示器上看到的颜色。
要向实现提供 HDR 元数据,请调用
// Provided by VK_EXT_hdr_metadata
void vkSetHdrMetadataEXT(
VkDevice device,
uint32_t swapchainCount,
const VkSwapchainKHR* pSwapchains,
const VkHdrMetadataEXT* pMetadata);
-
device是创建交换链的逻辑设备。 -
swapchainCount是pSwapchains中包含的交换链的数量。 -
pSwapchains是指向swapchainCount个 VkSwapchainKHR 句柄的数组的指针。 -
pMetadata是指向swapchainCount个 VkHdrMetadataEXT 结构的数组的指针。
元数据将在下一个使用该 VkSwapchainKHR 对象的 vkQueuePresentKHR 调用时应用于指定的 VkSwapchainKHR 对象。元数据将持续存在,直到后续的 vkSetHdrMetadataEXT 更改它为止。
VkHdrMetadataEXT 结构体定义如下:
// Provided by VK_EXT_hdr_metadata
typedef struct VkHdrMetadataEXT {
VkStructureType sType;
const void* pNext;
VkXYColorEXT displayPrimaryRed;
VkXYColorEXT displayPrimaryGreen;
VkXYColorEXT displayPrimaryBlue;
VkXYColorEXT whitePoint;
float maxLuminance;
float minLuminance;
float maxContentLightLevel;
float maxFrameAverageLightLevel;
} VkHdrMetadataEXT;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
displayPrimaryRed是一个 VkXYColorEXT 结构体,指定用于优化内容的显示器的红色原色。 -
displayPrimaryGreen是一个 VkXYColorEXT 结构体,指定用于优化内容的显示器的绿色原色。 -
displayPrimaryBlue是一个 VkXYColorEXT 结构体,指定用于优化内容的显示器的蓝色原色。 -
whitePoint是一个 VkXYColorEXT 结构体,指定用于优化内容的显示器的白点。 -
maxLuminance是用于优化内容的显示器的最大亮度,单位为尼特。 -
minLuminance是用于优化内容的显示器的最小亮度,单位为尼特。 -
maxContentLightLevel是所显示图像中最亮像素的期望亮度值,单位为尼特。 -
maxFrameAverageLightLevel是内容中任何位置具有最亮平均亮度的帧的平均亮度值,单位为尼特。
如果上述任何值未知,则它们 可以 设置为 0。
|
此处提供的元数据旨在按照 SMPTE 2086、CTA 861.3 和 CIE 15:2004 规范中的定义使用。此数据的有效性和使用超出 Vulkan 的范围。 |
当 hdrVivid 功能启用时,可以通过在 VkHdrMetadataEXT 的 pNext 链中包含 VkHdrVividDynamicMetadataHUAWEI 来设置 HDR Vivid 动态元数据,以控制内容的再现。
VkHdrVividDynamicMetadataHUAWEI 结构体定义如下:
// Provided by VK_HUAWEI_hdr_vivid
typedef struct VkHdrVividDynamicMetadataHUAWEI {
VkStructureType sType;
const void* pNext;
size_t dynamicMetadataSize;
const void* pDynamicMetadata;
} VkHdrVividDynamicMetadataHUAWEI;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
dynamicMetadataSize是动态元数据的大小,单位为字节。 -
pDynamicMetadata是指向动态元数据的指针。
|
HDR Vivid 元数据旨在按照 T/UWA 005.1-2022 规范中的定义使用。此数据的有效性和使用超出 Vulkan 的范围。 |
VkXYColorEXT 结构体定义如下:
// Provided by VK_EXT_hdr_metadata
typedef struct VkXYColorEXT {
float x;
float y;
} VkXYColorEXT;
-
x是 x 色度坐标。 -
y是 y 色度坐标。
色度坐标按照 CIE 15:2004 “Calculation of chromaticity coordinates” (第 7.3 节)中的规定,且对于真实颜色,其值限制在 0 到 1 之间。
延迟控制
某些实现支持扩展以减少显示延迟并控制交换链的显示间隔,本节的其余部分将对此进行描述。
抗延迟
VK_AMD_anti_lag 扩展降低了接收输入和在屏幕上显示之间的延迟。它添加了一个命令,以指示何时正在处理帧的输入,以及何时显示该帧的图像。
为了降低延迟,请调用
// Provided by VK_AMD_anti_lag
void vkAntiLagUpdateAMD(
VkDevice device,
const VkAntiLagDataAMD* pData);
-
device是逻辑设备 -
pData是指向包含延迟减少参数的 VkAntiLagDataAMD 结构体的指针。
此命令应在应用程序处理用户输入之前立即执行。如果 pData 不为 NULL 且 VkAntiLagDataAMD::presentationInfo 不为 NULL,则此命令 应在 vkQueuePresentKHR 之前再次执行,并将 pPresentationInfo 设置为匹配的值。
VkAntiLagDataAMD 结构体定义如下:
// Provided by VK_AMD_anti_lag
typedef struct VkAntiLagDataAMD {
VkStructureType sType;
const void* pNext;
VkAntiLagModeAMD mode;
uint32_t maxFPS;
const VkAntiLagPresentationInfoAMD* pPresentationInfo;
} VkAntiLagDataAMD;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
mode是一个 VkAntiLagModeAMD 值,指定抗延迟状态。 -
maxFPS是应用程序使用的帧速率限制,单位为每秒帧数。如果启用了抗延迟,则会施加此限制。如果应用程序尝试更快地渲染,则帧速率将降低以匹配此限制。值为 0 将禁用限制。 -
pPresentationInfo是指向 VkAntiLagPresentationInfoAMD 结构体的指针,其中包含有关应用程序阶段的信息。
此结构体指定抗延迟参数。
VkAntiLagDataAMD::mode 的可能值(指定抗延迟状态)如下:
// Provided by VK_AMD_anti_lag
typedef enum VkAntiLagModeAMD {
VK_ANTI_LAG_MODE_DRIVER_CONTROL_AMD = 0,
VK_ANTI_LAG_MODE_ON_AMD = 1,
VK_ANTI_LAG_MODE_OFF_AMD = 2,
} VkAntiLagModeAMD;
-
VK_ANTI_LAG_MODE_DRIVER_CONTROL_AMD指定是否启用或禁用抗延迟将取决于驱动程序设置。 -
VK_ANTI_LAG_MODE_ON_AMD指定将启用抗延迟。 -
VK_ANTI_LAG_MODE_OFF_AMD指定将禁用抗延迟。
VkAntiLagPresentationInfoAMD 结构体定义如下:
// Provided by VK_AMD_anti_lag
typedef struct VkAntiLagPresentationInfoAMD {
VkStructureType sType;
void* pNext;
VkAntiLagStageAMD stage;
uint64_t frameIndex;
} VkAntiLagPresentationInfoAMD;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
stage是一个 VkAntiLagStageAMD 值,指定当前的应用程序阶段。 -
frameIndex在应用程序处理输入数据 (VK_ANTI_LAG_STAGE_INPUT_AMD) 之前设置。在通过 vkQueuePresentKHR (VK_ANTI_LAG_STAGE_PRESENT_AMD) 呈现包含当前输入数据的帧之前,**应该** 设置相同的frameIndex值。每个帧都**应该**这样做。
此结构体指定要为其设置防延迟参数的呈现阶段的信息。
指定当前应用程序阶段的 VkAntiLagPresentationInfoAMD::stage 的可能值为
// Provided by VK_AMD_anti_lag
typedef enum VkAntiLagStageAMD {
VK_ANTI_LAG_STAGE_INPUT_AMD = 0,
VK_ANTI_LAG_STAGE_PRESENT_AMD = 1,
} VkAntiLagStageAMD;
-
VK_ANTI_LAG_STAGE_INPUT_AMD指定处理输入之前的阶段。 -
VK_ANTI_LAG_STAGE_PRESENT_AMD指定 vkQueuePresentKHR 之前的阶段。
延迟降低
要在交换链上启用或禁用低延迟模式,请调用
// Provided by VK_NV_low_latency2
VkResult vkSetLatencySleepModeNV(
VkDevice device,
VkSwapchainKHR swapchain,
const VkLatencySleepModeInfoNV* pSleepModeInfo);
-
device是与swapchain关联的设备。 -
swapchain是要在其上启用或禁用低延迟模式的交换链。 -
pSleepModeInfo是NULL或指向 VkLatencySleepModeInfoNV 结构体的指针,该结构体指定了延迟睡眠模式的参数。
如果 pSleepModeInfo 为 NULL,则 vkSetLatencySleepModeNV 将禁用低延迟模式、低延迟加速,并将之前由 VkLatencySleepModeInfoNV 指定的最小呈现间隔设置为 swapchain 上的零。作为对外部同步对象正常规则的例外,传递给 vkSetLatencySleepModeNV 的交换链**可以**被其他线程同时用于调用除 vkDestroySwapchainKHR 之外的函数。对与此扩展相关的交换链数据的访问**必须**在实现中是原子的。
VkLatencySleepModeInfoNV 结构体定义如下
// Provided by VK_NV_low_latency2
typedef struct VkLatencySleepModeInfoNV {
VkStructureType sType;
const void* pNext;
VkBool32 lowLatencyMode;
VkBool32 lowLatencyBoost;
uint32_t minimumIntervalUs;
} VkLatencySleepModeInfoNV;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
lowLatencyMode是用于启用或禁用低延迟模式的开关。 -
lowLatencyBoost允许应用程序提示 GPU 提高性能,以在增加功耗的情况下提供额外的延迟节省。 -
minimumIntervalUs是对于给定的交换链,vkLatencySleepNV 将强制执行的 vkQueuePresentKHR 调用之间的微秒数。
如果 lowLatencyMode 为 VK_FALSE,则 lowLatencyBoost 仍将提示 GPU 提高其功耗状态,并且 vkLatencySleepNV 仍将在 vkQueuePresentKHR 调用之间强制执行 minimumIntervalUs。
为了提供用于延迟主机 CPU 工作以实现更低延迟渲染的同步原语,请调用
// Provided by VK_NV_low_latency2
VkResult vkLatencySleepNV(
VkDevice device,
VkSwapchainKHR swapchain,
const VkLatencySleepInfoNV* pSleepInfo);
-
device是与swapchain关联的设备。 -
swapchain是用于基于 VkLatencySubmissionPresentIdNV 提交延迟关联 CPU 工作的交换链。 -
pSleepInfo是指向 VkLatencySleepInfoNV 结构体的指针,该结构体指定了延迟睡眠的参数。
vkLatencySleepNV 立即返回。应用程序**应该**使用带有 pSleepInfo->signalSemaphore 的 vkWaitSemaphores 来延迟主机 CPU 工作。CPU 工作是指在呈现之前完成的应用程序工作,包括但不限于:输入采样、模拟、命令缓冲区记录、命令缓冲区提交和呈现提交。应用程序**应该**在输入采样之前调用此函数,并且在每次呈现之间调用一次。
VkLatencySleepInfoNV 结构体定义如下
// Provided by VK_NV_low_latency2
typedef struct VkLatencySleepInfoNV {
VkStructureType sType;
const void* pNext;
VkSemaphore signalSemaphore;
uint64_t value;
} VkLatencySleepInfoNV;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
signalSemaphore是一个信号量,它被发出信号以指示应用程序**应该**恢复输入采样工作。 -
value是signalSemaphore被设置为恢复采样工作的值。
应用程序**可以**通过调用在帧生成工作的各个阶段提供时间戳
// Provided by VK_NV_low_latency2
void vkSetLatencyMarkerNV(
VkDevice device,
VkSwapchainKHR swapchain,
const VkSetLatencyMarkerInfoNV* pLatencyMarkerInfo);
-
device是与swapchain关联的设备。 -
swapchain是在其上捕获时间戳的交换链。 -
pSetLatencyMarkerInfo是指向 VkSetLatencyMarkerInfoNV 结构体的指针,该结构体指定了要设置的标记的参数。
在模拟和渲染线程的开始和结束以及 vkQueuePresentKHR 调用的开始和结束时,**可以**调用 vkSetLatencyMarkerNV 以提供应用程序参考的时间戳。这些时间戳与调用 vkGetLatencyTimingsNV 一起返回,同时返回驱动程序在应用程序内与延迟相关的各个兴趣点提供的时间戳。作为对外部同步对象正常规则的例外,传递给 vkSetLatencyMarkerNV 的交换链**可以**被其他线程同时用于调用除 vkDestroySwapchainKHR 之外的函数。对与此扩展相关的交换链数据的访问**必须**在实现中是原子的。
VkSetLatencyMarkerInfoNV 结构定义如下:
// Provided by VK_NV_low_latency2
typedef struct VkSetLatencyMarkerInfoNV {
VkStructureType sType;
const void* pNext;
uint64_t presentID;
VkLatencyMarkerNV marker;
} VkSetLatencyMarkerInfoNV;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
presentID是应用程序提供的值,用于将时间戳与使用 VkPresentIdKHR::pPresentIds的vkQueuePresentKHR命令关联,以用于给定的 present。 -
marker是要记录的时间戳类型。
VkLatencyMarkerNV 枚举定义如下:
// Provided by VK_NV_low_latency2
typedef enum VkLatencyMarkerNV {
VK_LATENCY_MARKER_SIMULATION_START_NV = 0,
VK_LATENCY_MARKER_SIMULATION_END_NV = 1,
VK_LATENCY_MARKER_RENDERSUBMIT_START_NV = 2,
VK_LATENCY_MARKER_RENDERSUBMIT_END_NV = 3,
VK_LATENCY_MARKER_PRESENT_START_NV = 4,
VK_LATENCY_MARKER_PRESENT_END_NV = 5,
VK_LATENCY_MARKER_INPUT_SAMPLE_NV = 6,
VK_LATENCY_MARKER_TRIGGER_FLASH_NV = 7,
VK_LATENCY_MARKER_OUT_OF_BAND_RENDERSUBMIT_START_NV = 8,
VK_LATENCY_MARKER_OUT_OF_BAND_RENDERSUBMIT_END_NV = 9,
VK_LATENCY_MARKER_OUT_OF_BAND_PRESENT_START_NV = 10,
VK_LATENCY_MARKER_OUT_OF_BAND_PRESENT_END_NV = 11,
} VkLatencyMarkerNV;
VkLatencyMarkerNV 的成员用作 vkSetLatencyMarkerNV 的参数,用于以下描述的用例中
-
VK_LATENCY_MARKER_SIMULATION_START_NV应该在每帧模拟执行开始时调用,但在调用vkLatencySleepNV之后。 -
VK_LATENCY_MARKER_SIMULATION_END_NV应该在每帧模拟执行结束时调用。 -
VK_LATENCY_MARKER_RENDERSUBMIT_START_NV应该在每帧渲染提交执行开始时调用。这 应该 在调用 Vulkan API 的任何位置,并且 必须 不跨越到异步渲染。 -
VK_LATENCY_MARKER_RENDERSUBMIT_END_NV应该在每帧渲染提交执行结束时调用。 -
VK_LATENCY_MARKER_PRESENT_START_NV应该在vkQueuePresentKHR之前调用。 -
VK_LATENCY_MARKER_PRESENT_END_NV应该在vkQueuePresentKHR返回时调用。 -
VK_LATENCY_MARKER_INPUT_SAMPLE_NV应该在应用程序收集输入数据之前调用。 -
VK_LATENCY_MARKER_TRIGGER_FLASH_NV应该在VK_LATENCY_MARKER_SIMULATION_START_NV和VK_LATENCY_MARKER_SIMULATION_END_NV之间的任何位置调用,每当发生鼠标左键单击时调用。
要获取包含最新收集的延迟数据的数组,请调用
// Provided by VK_NV_low_latency2
void vkGetLatencyTimingsNV(
VkDevice device,
VkSwapchainKHR swapchain,
VkGetLatencyMarkerInfoNV* pLatencyMarkerInfo);
-
device是与swapchain关联的设备。 -
swapchain是从中返回数据的交换链。 -
pGetLatencyMarkerInfo是指向 VkGetLatencyMarkerInfoNV 结构的指针,该结构指定返回延迟信息的参数。
vkGetLatencyTimingsNV 返回的时间包含从 vkSetLatencyMarkerNV 请求的时间戳以及 VkLatencyTimingsFrameReportNV 中定义的其他特定于实现的标记。
VkGetLatencyMarkerInfoNV 结构定义如下:
// Provided by VK_NV_low_latency2
typedef struct VkGetLatencyMarkerInfoNV {
VkStructureType sType;
const void* pNext;
uint32_t timingCount;
VkLatencyTimingsFrameReportNV* pTimings;
} VkGetLatencyMarkerInfoNV;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext要么是NULL,要么是指向扩展此结构的结构的指针。 -
timingCount是一个整数,与可用或查询的先前帧延迟数据的数量相关,如下所述。 -
pTimings要么是NULL,要么是指向 VkLatencyTimingsFrameReportNV 结构数组的指针。
如果 pTimings 为 NULL,则最大可查询的帧数据量将在 timingCount 中返回。否则,timingCount 必须由应用程序设置为 pTimings 数组中的元素数量,并且在返回时,该变量将被实际写入 pTimings 的值的数量覆盖。 pTimings 的元素按照它们被请求的顺序排列,最旧的数据在第一个条目中。
VkLatencyTimingsFrameReportNV 结构描述了 vkGetLatencyTimingsNV 返回的延迟数据
// Provided by VK_NV_low_latency2
typedef struct VkLatencyTimingsFrameReportNV {
VkStructureType sType;
const void* pNext;
uint64_t presentID;
uint64_t inputSampleTimeUs;
uint64_t simStartTimeUs;
uint64_t simEndTimeUs;
uint64_t renderSubmitStartTimeUs;
uint64_t renderSubmitEndTimeUs;
uint64_t presentStartTimeUs;
uint64_t presentEndTimeUs;
uint64_t driverStartTimeUs;
uint64_t driverEndTimeUs;
uint64_t osRenderQueueStartTimeUs;
uint64_t osRenderQueueEndTimeUs;
uint64_t gpuRenderStartTimeUs;
uint64_t gpuRenderEndTimeUs;
} VkLatencyTimingsFrameReportNV;
VkLatencyTimingsFrameReportNV 结构的成员描述如下
-
presentID是应用程序提供的值,用于将时间戳与使用 VkPresentIdKHR::pPresentIds的vkQueuePresentKHR命令关联,以用于给定的 present。 -
simStartTimeUs是当使用VkLatencyMarkerNV枚举VK_LATENCY_MARKER_SIMULATION_START_NV调用vkSetLatencyMarkerNV时写入的时间戳。 -
simEndTimeUs是当使用VkLatencyMarkerNV枚举VK_LATENCY_MARKER_SIMULATION_END_NV调用vkSetLatencyMarkerNV时写入的时间戳 -
renderStartTimeUs是当使用VkLatencyMarkerNV枚举VK_LATENCY_MARKER_RENDERSUBMIT_START_NV调用vkSetLatencyMarkerNV时写入的时间戳。 -
renderEndTimeUs是当使用VkLatencyMarkerNV枚举VK_LATENCY_MARKER_RENDERSUBMIT_END_NV调用vkSetLatencyMarkerNV时写入的时间戳。 -
presentStartTimeUs是当使用VkLatencyMarkerNV枚举VK_LATENCY_MARKER_PRESENT_START_NV调用vkSetLatencyMarkerNV时写入的时间戳。 -
presentEndTimeUs是当使用VkLatencyMarkerNV枚举VK_LATENCY_MARKER_PRESENT_END_NV调用vkSetLatencyMarkerNV时写入的时间戳。 -
driverStartTimeUs是在调用帧的第一个vkQueueSubmit时写入的时间戳。 -
driverEndTimeUs是当最终的vkQueueSubmit从 Vulkan 驱动程序移交时写入的时间戳。 -
osRenderQueueStartTimeUs是当最终的vkQueueSubmit从 Vulkan 驱动程序移交时写入的时间戳。 -
osRenderQueueEndTimeUs是当第一个提交到达 GPU 时写入的时间戳。 -
gpuRenderStartTimeUs是当第一个提交到达 GPU 时写入的时间戳。 -
gpuRenderEndTimeUs是当帧的最终提交在 GPU 上完成时写入的时间戳。
VkLatencySubmissionPresentIdNV 结构定义如下:
// Provided by VK_NV_low_latency2
typedef struct VkLatencySubmissionPresentIdNV {
VkStructureType sType;
const void* pNext;
uint64_t presentID;
} VkLatencySubmissionPresentIdNV;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
presentID用于将vkQueueSubmit与给定vkQueuePresentKHR使用的 presentId 通过 VkPresentIdKHR::pPresentIds进行关联。
对于任何需要使用低延迟模式步调跟踪的提交,它需要与给定 present 中的其他提交关联。为了将提交与低延迟模式的 presentID 关联,vkQueueSubmit 的 pNext 链必须包含一个 VkLatencySubmissionPresentIdNV 结构。
要将队列标记为带外,以便忽略该队列上的所有 vkQueueSubmit 调用以进行延迟评估,请调用
// Provided by VK_NV_low_latency2
void vkQueueNotifyOutOfBandNV(
VkQueue queue,
const VkOutOfBandQueueTypeInfoNV* pQueueTypeInfo);
-
queue是要标记为带外的 VkQueue。 -
pQueueTypeInfo是指向 VkOutOfBandQueueTypeInfoNV 结构的指针,该结构指定队列类型。
VkOutOfBandQueueTypeInfoNV 结构定义如下
// Provided by VK_NV_low_latency2
typedef struct VkOutOfBandQueueTypeInfoNV {
VkStructureType sType;
const void* pNext;
VkOutOfBandQueueTypeNV queueType;
} VkOutOfBandQueueTypeInfoNV;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
queueType描述要标记为带外的队列的用途。
VkOutOfBandQueueTypeNV 枚举定义如下
// Provided by VK_NV_low_latency2
typedef enum VkOutOfBandQueueTypeNV {
VK_OUT_OF_BAND_QUEUE_TYPE_RENDER_NV = 0,
VK_OUT_OF_BAND_QUEUE_TYPE_PRESENT_NV = 1,
} VkOutOfBandQueueTypeNV;
VkOutOfBandQueueTypeNV 的成员用于描述 VkOutOfBandQueueTypeInfoNV 中的队列类型,如下所述
-
VK_OUT_OF_BAND_QUEUE_TYPE_RENDER_NV指定工作将提交到此队列。 -
VK_OUT_OF_BAND_QUEUE_TYPE_PRESENT_NV指定将从此队列进行呈现。
要允许交换链使用低延迟模式,请将 VkSwapchainLatencyCreateInfoNV 结构添加到 VkSwapchainCreateInfoKHR 的 pNext 链中。
VkSwapchainLatencyCreateInfoNV 结构定义如下
// Provided by VK_NV_low_latency2
typedef struct VkSwapchainLatencyCreateInfoNV {
VkStructureType sType;
const void* pNext;
VkBool32 latencyModeEnable;
} VkSwapchainLatencyCreateInfoNV;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
如果创建的交换链将利用低延迟模式,则
latencyModeEnable为VK_TRUE,否则为VK_FALSE。
VkLatencySurfaceCapabilitiesNV 结构定义如下
// Provided by VK_NV_low_latency2
typedef struct VkLatencySurfaceCapabilitiesNV {
VkStructureType sType;
const void* pNext;
uint32_t presentModeCount;
VkPresentModeKHR* pPresentModes;
} VkLatencySurfaceCapabilitiesNV;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
presentModeCount是提供的呈现模式的数量。 -
pPresentModes是针对低延迟模式优化的呈现模式列表,其中包含presentModeCount个条目。
如果 pPresentModes 为 NULL,则在 presentModeCount 中返回针对低延迟模式优化的呈现模式的数量。否则,应用程序必须将 presentModeCount 设置为 pPresentModes 数组中的元素数量,并在返回时,该变量将被实际写入 pPresentModes 的值覆盖。如果 presentModeCount 的值小于优化的呈现模式数量,则最多会将 presentModeCount 个值写入 pPresentModes。
呈现屏障
VK_NV_present_barrier 扩展允许应用程序使用呈现屏障跨多个交换链同步相应的呈现请求。如果通过将 VkSwapchainPresentBarrierCreateInfoNV 结构添加到 VkSwapchainCreateInfoKHR 结构的 pNext 链,并将 VkSwapchainPresentBarrierCreateInfoNV::presentBarrierEnable 设置为 true 来创建交换链,则该交换链被认为正在使用呈现屏障。
一组相应的呈现请求定义为与每个使用呈现屏障的交换链关联的恰好一个排队呈现请求,无论该排队请求是否已执行。当调用 vkQueuePresentKHR 并指定使用呈现屏障的交换链创建给定呈现请求时,该请求将添加到最旧的现有相应请求集中,其中不存在与该请求的交换链关联的成员,或者如果不存在此类集,则添加到新的相应请求集中。
当一组相应的请求包含来自每个使用呈现屏障的交换链的一个请求时,该请求集被认为是完整的。通过实现延迟将图像排队呈现到使用呈现屏障的交换链,直到相应的请求集完整为止,并且该集中所有请求的可见性操作(如 vkQueuePresentKHR 所述)都已完成。
此外,使用呈现屏障的交换链集可以在同一进程中,也可以在同一操作系统下运行的不同进程中。如果所需的同步硬件已连接且配置正确,则此扩展还支持应用程序使用呈现屏障跨分布式系统同步相应的呈现请求。但是,所需硬件的配置机制不在 Vulkan 规范和此扩展的范围内。
// Provided by VK_NV_present_barrier
typedef struct VkSwapchainPresentBarrierCreateInfoNV {
VkStructureType sType;
void* pNext;
VkBool32 presentBarrierEnable;
} VkSwapchainPresentBarrierCreateInfoNV;
-
sType是一个 VkStructureType 值,用于标识此结构。 -
pNext可以是NULL,也可以是指向扩展此结构的结构的指针。 -
presentBarrierEnable是一个布尔值,指示是否请求使用呈现屏障。
如果 VkSwapchainCreateInfoKHR 的 pNext 链不包含此结构,则 presentBarrierEnable 的默认值为 VK_FALSE,这意味着交换链不请求使用呈现屏障。此外,当重新创建正在使用呈现屏障的交换链,并且 VkSwapchainCreateInfoKHR 的 pNext 链不包含此结构时,这意味着交换链将停止使用呈现屏障。