窗口系统集成 (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 服务器的连接。 -
rrOutput
X11 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
显示器所在的物理设备。 -
drmFd
DRM 主文件描述符。 -
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
用于查询显示器的物理设备。 -
drmFd
DRM 主文件描述符。 -
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
链不包含此结构时,这意味着交换链将停止使用呈现屏障。