From 3bc0f7927d992fff72996bf6f1e9d6ddb08ec832 Mon Sep 17 00:00:00 2001 From: Ian Elliott Date: Thu, 10 May 2018 15:01:21 -0600 Subject: [PATCH] WIP: Add the VK_EXT_present_timing extension This extension allows an application that uses the VK_KHR_swapchain extension to obtain information about the presentation engine's display, to obtain timing information about each present operation, and to schedule a present to happen at a specific time. Applications can use this to minimize various visual anomalies (e.g., stuttering). --- appendices/VK_EXT_present_timing.txt | 255 ++++++++++ appendices/glossary.txt | 38 ++ .../VK_EXT_present_timing/PresentTimeInfo.txt | 184 ++++++++ chapters/VK_EXT_present_timing/queries.txt | 441 ++++++++++++++++++ chapters/VK_GOOGLE_display_timing/queries.txt | 86 +--- chapters/VK_KHR_surface/wsi.txt | 29 +- chapters/VK_KHR_swapchain/wsi.txt | 13 + chapters/synchronization.txt | 7 + xml/vk.xml | 104 ++++- 9 files changed, 1065 insertions(+), 92 deletions(-) create mode 100644 appendices/VK_EXT_present_timing.txt create mode 100644 chapters/VK_EXT_present_timing/PresentTimeInfo.txt create mode 100644 chapters/VK_EXT_present_timing/queries.txt diff --git a/appendices/VK_EXT_present_timing.txt b/appendices/VK_EXT_present_timing.txt new file mode 100644 index 0000000000..38a906d845 --- /dev/null +++ b/appendices/VK_EXT_present_timing.txt @@ -0,0 +1,255 @@ +// Copyright (c) 2017-2020 Khronos Group. +// +// SPDX-License-Identifier: CC-BY-4.0 + +include::{generated}/meta/{refprefix}VK_EXT_present_timing.txt[] + +*Last Modified Date*:: + 2020-07-06 +*IP Status*:: + No known IP claims. +*Contributors*:: + - Ian Elliott, Google + - James Jones, NVIDIA + - Jeff Juliano, NVIDIA + - Daniel Rakos, AMD + - Daniel Stone, Collabora + - Daniel Vetter, Intel + - Aric Cyr, AMD + - Jason Eckstrand, Intel + - Nicolai Hähnle, AMD + - Alon Or-Bach, Samsung + - Niklas Smedberg, Unity Technologies + - Tobias Hector, AMD + +This device extension allows an application that uses the +`<>` extension to obtain information about the +presentation engine's display, to obtain timing information about each +present, and to schedule a present to happen no earlier than a desired time. +An application can use this to minimize various visual anomalies (e.g. +stuttering). + +Traditional game and real-time animation applications need to correctly +position their geometry for when the presentable image will be presented to +the user. +To accomplish this, applications need various timing information about the +presentation engine's display. +They need to know when presentable images were actually presented, and when +they could have been presented. +Applications also need to tell the presentation engine to display an image +no sooner than a given time. +This allows the application to avoid stuttering, so the animation looks +smooth to the user. + + +include::{generated}/interfaces/VK_EXT_present_timing.txt[] + +=== Issues + +1) How does the application determine refresh duration, quanta for change, +whether FRR vs. VRR, etc. + +*PROPOSED*: the query returns two values: 1) a refresh-cycle duration +(pname:refreshDuration), and 2) an indication whether the timing is +currently fixed (FRR) or variable (VRR). +If pname:refreshDuration is zero, the platform cannot supply these +values until after at least one flink:vkQueuePresentKHR has been done, +from this time (e.g. if flink:vkQueuePresentKHR has been previously +called for this swapchain, at least one additional call must be made). +After calling flink:vkQueuePresentKHR, the query can be repeated until +pname:refreshDuration is non-zero, at which point the FRR vs. VRR +indication will also be valid. + +If the presentation engine's pname:refreshDuration is a fixed value, +the application's image present duration (IPD) must be a multiple of +pname:refreshDuration. +That is, the quanta for changing the IPD is pname:refreshDuration. +For example, if pname:refreshDuration is 16.67ms, the IPD can be +16.67ms, 33.33ms, 50.0ms, etc. + +If the presentation engine's pname:refreshDuration is variable, +pname:refreshDuration is the minimum value of the application's IPD, and +the IPD can be larger by any quanta that is meaningful to the application. +For example, if the pname:refreshDuration is 10ms (i.e. the maximum +refresh rate is 100Hz), the application can choose an IPD of 11ms, +13.33ms, 13.5ms, or 66.0ms; any value greater than or equal to 10ms is +valid. +There may be negative consequences for choosing an IPD that is too +high, as the presentation engine may actually have a practical maximum +pname:refreshDuration, where it needs to display the previous image +again, and during this time the presentation engine might delay +displaying a newly-presented image. + +FRR displays on at least one platform (Wayland) are not necessarily +fixed; but can change over time. +For example, if a full-screen video player application is visible, the display +may operate at a 24Hz refresh cycle; and then later switch to 60Hz when +multiple windows are visible. +The special value of zero for pname:refreshDuration is used to +indicate the condition where the platform cannot yet answer the query. + +VRR displays on some platforms can also be seen as having different +characteristics over time. +For example, if an application's window is full-screen-exclusive (i.e. no other +window or window system component is visible), the display can look like a VRR +display (however that is defined). +If the application's window is not full-screen-exclusive (e.g. a normal +multi-window case), the display can look like an FRR display (i.e. because the +compositor is trying to treat all windows in a consistent manner). +A different issue will deal with these how the timing characteristics +can change over time. + + +2) Do we return min/max Values for Refresh Duration for VRR? + +*PROPOSED*: return only the minimum value of refreshDuration for a VRR. + +VRR displays have a minimum and maximum refresh rate, and therefore a minimum +and maximum refreshDuration. +It has been asserted that the display effectively does not have a minimum +refresh rate. +That is because if an application doesn't present soon enough, the display +hardware will automatically re-display the previous image. +However, when the display does that, an application cannot present a new image +for a certain period of time. +It is unclear about whether that period is large enough to cause visual +artifacts. + + +3) How to deal with changes in timing properties? + +*RESOLVED*: The slink:VkPastPresentationTimingEXT structure that is +returned by flink:vkGetPastPresentationTimingEXT will contain +pname:timeDomainChanged, which will be ename:VK_TRUE if the time +domain enabled for the swapchain is not currently available. + +An example of why display timing properties can change is if a surface +changes from being a window that’s a subset of the display size, to +becoming full-screen-exclusive. +While the surface was a subset of the display, a compositor might +enforce fixed timings on the surface (e.g. FRR of 60Hz), where the +presentation engine might be free to allow VRR behavior of a +full-screen-exclusive surface. + +It is possible that a full-screen-exclusive window can become +temporarily obscured (e.g. when a short-term dialog pops up). +In this case, the surface might use FRR timings while the dialog is +visible and VRR otherwise. + + +4) One Query for all Timing info vs. an initial query to determine FRR vs. VRR, +and then FRR-specific vs VRR-specific queries? + +*PROPOSED*: Have one query, as described in issue 1, that can be +called whenever the application needs to obtain the timing properties +of the surface. + + +5) Query to Determine Time Domain? + +*PROPOSED*: Have a query to determine the time domain. +This extension will define some return values, including some that are +platform-specific. +Other extensions can add other time domains. + + +6) What Time to use for targetPresentTime for Early Images? + +*PROPOSED*: Have no query for determining the current time in the PE’s time +domain; and do allow the special value of zero for targetPresentTime and +idealPresentTime, meaning that there is no target nor ideal time. + +On some platforms, there is no way to determine the current time, nor +to determine surface timing properties until after at least one image +has been presented. + +In such cases, the special value of zero allows the application to +indicate that timing feedback is desired, but that no +targetPresentTime nor idealPresentTime is requested. +Later, once the application has obtained feedback, it can specify +targetPresentTime and idealPresentTime. + + +7) How long before an application’s request for new image duration is honored? + +*UNRESOLVED*: Apparently, changes to some vendors' display hardware settings do +not take effect immediately. +It is not clear what settings, and therefore, it is not clear how to +address this issue. + + +8) Do we have a query for the anticipated latency from present to feedback? + +*UNRESOLVED*: There is some amount of latency from when an application calls +vkQueuePresentKHR to when the image is displayed to the user, to when feedback +is available to the application on when the image was actually displayed to the +user. +The first time (from the call till the image is presented) generally doesn’t +matter, because the application will likely be providing a targetPresentTime +(i.e. the application may have some indication for how long this will be). +However, the latency between targetPresentTime until feedback is available may +be much long. +For example, on Android on the 1st-generation Pixel phone (60Hz FRR display), +the latency was approximately 5 refresh cycles (83.33ms). +For higher-frequency displays, the latency may have a larger number of refresh +cycles. + +Is there value in having a query for the application to know how long it may +have to wait for feedback? +Can such a query be reasonably answered by the driver? + +Is there other interesting information in this space that we may wish to +capture? + + +9) Do we have a query(s) about the number of VkPastPresentationTimingEXT +structs to keep? + +*UNRESOLVED*: At the Montreal F2F, there was discussion about how much +feedback that the driver needs to keep and/or how much feedback that +the application needs to be able to query. + +The way that the LunarG cube demo (official WSI example code) used +VK_GOOGLE_display_timing, and what is proposed for the new extension is that +the application query what feedback is available during every render-present +loop. +If the application never skips querying for feedback, and always obtains +whatever feedback is available, there doesn’t seem much need for such a +query(s). +What I saw with the cube demo on a Pixel phone was that most of the time, the +application obtained feedback for 1 previous present. +Occassionally, it would get 2 VkPastPresentationTimingEXT structs on time and +then 0 the next (or vice versa). + +Perhaps, a video player application might present several images at once, and +then later get feedback for several images at the same time. +That would be the most-likely use-case that I can come up with for why a query +might be useful. +Is that compelling enough? + +What might the model for the query(s) be? +Potentially the application can tell the driver how many presents it might do +at a time, and the driver can use that to size its internal buffer. +Is there value in having a query that would influence the driver’s behavior +(beyond what’s provided for in the currently-proposed API)? + +10) How is the SWAPCHAIN_LOCAL time domain used with the calibrated +timestamps extension? + +PROPOSED: Define a struct to chain into VkCalibratedTimestampInfoEXT::pNext +that specifies a swapchain. +Is anything additional needed for +vkGetPhysicalDeviceCalibrateableTimeDomainsEXT, or are swapchain-local +timestamps always calibrateable or always not calibrateable for a given +device? + +11) Should VK_PRESENT_MODE_FIFO_LATEST_READY_EXT be part of this extension, +or split out into its own extension? + +PROPOSED: It is only tangentially related. +Split it out into its own extension and define the interaction here. + +=== Version History + + * Revision 1, 2018-05-11 (Ian Elliott) + - Internal revisions diff --git a/appendices/glossary.txt b/appendices/glossary.txt index 295af3ac06..297f48f6e5 100644 --- a/appendices/glossary.txt +++ b/appendices/glossary.txt @@ -633,6 +633,11 @@ Framebuffer Region:: A framebuffer region is a set of sample (x, y, layer, sample) coordinates that is a subset of the entire framebuffer. +ifdef::VK_EXT_present_timing,VK_GOOGLE_display_timing[] +Frame Rate:: + A non-Vulkan term for Image Present Rate (IPR). +endif::VK_EXT_present_timing,VK_GOOGLE_display_timing[] + Front-Facing:: See Facingness. @@ -711,6 +716,18 @@ Image:: of device memory. Represented by a slink:VkImage object. +ifdef::VK_EXT_present_timing,VK_GOOGLE_display_timing[] +Image Present Duration:: + The amount of time the application intends for each + newly-presented image to be visible to the user. + This value should: be a multiple of the refresh cycle duration. + +Image Present Rate:: + The number of newly-presented images the application intends to present + each second (a.k.a. frame rate). + This value should: be a multiple of the refresh rate. +endif::VK_EXT_present_timing,VK_GOOGLE_display_timing[] + Image Subresource:: A specific mipmap level and layer of an image. @@ -888,6 +905,11 @@ Invocation Repack Instruction:: implementation may: change the set of invocations that are executing. endif::VK_KHR_ray_tracing,VK_NV_ray_tracing[] +ifdef::VK_EXT_present_timing,VK_GOOGLE_display_timing[] +IPD:: + Image Present Duration. +endif::VK_EXT_present_timing,VK_GOOGLE_display_timing[] + ifdef::VK_KHR_deferred_host_operations[] Join (Deferred Host Operations):: The act of instructing a thread to participate in the execution of a @@ -1311,10 +1333,26 @@ Queue Submission:: See the <> for more information. +ifdef::VK_EXT_present_timing,VK_GOOGLE_display_timing[] +RC:: + Refresh Cycle. +endif::VK_EXT_present_timing,VK_GOOGLE_display_timing[] + Recording State (Command Buffer):: A command buffer that is ready to record commands. See also Initial State and Executable State. +ifdef::VK_EXT_present_timing,VK_GOOGLE_display_timing[] +Refresh Cycle:: + The periodic process for updating the contents of the Presentation Engine's display. + +Refresh Cycle Duration:: + The amount of time from the start of one refresh cycle to the next. + +Refresh Rate:: + The number of refresh cycles per second. +endif::VK_EXT_present_timing,VK_GOOGLE_display_timing[] + Release Operation (Resource):: An operation that releases ownership of an image subresource or buffer range. diff --git a/chapters/VK_EXT_present_timing/PresentTimeInfo.txt b/chapters/VK_EXT_present_timing/PresentTimeInfo.txt new file mode 100644 index 0000000000..8a8ad39570 --- /dev/null +++ b/chapters/VK_EXT_present_timing/PresentTimeInfo.txt @@ -0,0 +1,184 @@ +// Copyright (c) 2014-2020 Khronos Group. +// +// SPDX-License-Identifier: CC-BY-4.0 + +[open,refpage='VkPresentTimesInfoEXT',desc='The earliest time each image should be presented',type='structs'] +-- + +When the `<>` extension is enabled, additional +fields can: be specified that allow an application to specify the earliest +time that an image should be displayed. +This allows an application to avoid stutter that is caused by an image being +displayed earlier than planned. +Such stuttering can occur with both fixed and variable-refresh-rate +displays, because stuttering occurs when the geometry is not correctly +positioned for when the image is displayed. +An application can: instruct the presentation engine that an image should +not be displayed earlier than a specified time by including the +sname:VkPresentTimesInfoEXT structure in the pname:pNext chain of the +sname:VkPresentInfoKHR structure. + +The sname:VkPresentTimesInfoEXT structure is defined as: + +include::{generated}/api/structs/VkPresentTimesInfoEXT.txt[] + + * pname:sType is the type of this structure. + * pname:pNext is `NULL` or a pointer to an extension-specific structure. + * pname:swapchainCount is the number of swapchains being presented to by + this command. + * pname:pTimes is `NULL` or a pointer to an array of + sname:VkPresentTimeEXT elements with pname:swapchainCount entries. + If not `NULL`, each element of pname:pTimes contains the earliest time + to present the image corresponding to the entry in the + sname:VkPresentInfoKHR::pname:pImageIndices array. + +.Valid Usage +**** + * [[VUID-VkPresentTimesInfoEXT-swapchainCount-01247]] + pname:swapchainCount must: be the same value as + sname:VkPresentInfoKHR::pname:swapchainCount, where + sname:VkPresentInfoKHR is in the pname:pNext chain of this + sname:VkPresentTimesInfoEXT structure. +**** + +include::{generated}/validity/structs/VkPresentTimesInfoEXT.txt[] +-- + +[open,refpage='VkPresentTimeEXT',desc='Specifying when an image should be presented',type='structs'] +-- + +The sname:VkPresentTimeEXT union contains either a +slink:VkAbsolutePresentTimeEXT or a slink:VkRelativePresentTimeEXT +structure, defined as: + +include::{generated}/api/structs/VkPresentTimeEXT.txt[] + +include::{generated}/validity/structs/VkPresentTimeEXT.txt[] +-- + +[open,refpage='VkAbsolutePresentTimeEXT',desc='Specifying the earliest time an image should be presented',type='structs'] +-- + +The sname:VkAbsolutePresentTimeEXT structure is defined as: + +include::{generated}/api/structs/VkAbsolutePresentTimeEXT.txt[] + + * pname:presentID is an application-provided identification value. + If non-zero, flink:vkGetPastPresentationTimingEXT will return a + slink:VkPastPresentationTimingEXT struct with the timing information + associated with the present to the associated swapchain for this + call to flink:vkQueuePresentKHR, including this value being in the + pname:presentID member of the slink:VkPastPresentationTimingEXT + struct. + In order to be useful to the application, it should: be unique within + some period of time that is meaningful to the application. + * pname:targetPresentTime, if non-zero, specifies the earliest time the + application wants the image to be displayed to the user. + pname:targetPresentTime is a time in nanoseconds, according to the + time-domain being used. + A value of zero specifies that the presentation engine may: display the + image at any time. + * pname:idealPresentTime provides an indication to the presentation + engine of what the application desires its IPD to become. + An application can: set pname:idealPresentTime to the same value + as pname:targetPresentTime, indicating that the application + desires its IPD to remain steady. + A value earlier than + pname:targetPresentTime indicates that the application desires to + shorten its IPD. + A value later than pname:targetPresentTime + indicates that the application desires to lengthen its IPD. + The presentation engine will provide feedback on this value in the + data returned by flink:vkGetPastPresentationTimingEXT. + * pname:presentSlop is the period of time in nanoseconds before + pname:targetPresentTime that the presentation engine may: display + the image. + +If pname:targetPresentTime is non-zero, the presentation engine should: +not display the image to the user at a time earlier than +(pname:targetPresentTime - pname:presentSlop). + +Setting pname:targetPresentTime to zero is useful when the application +desires to provide a non-zero pname:presentID in order to get back timing +information from flink:vkGetPastPresentationTimingEXT, but does not wish +to set a pname:targetPresentTime. + +Providing a pname:presentSlop enables the application to indicate to the +presentation engine to display the image within this period if a vertical +blanking period occurs on FRR displays. + +[NOTE] +.Note +==== +The pname:presentSlop is used to avoid unintentionally missing a vertical +blanking period on FRR displays due to rounding errors or drift between +clocks. +A suggested value for pname:presentSlop is half the _Refresh Rate_. +==== + +include::{generated}/validity/structs/VkAbsolutePresentTimeEXT.txt[] + +-- + +[open,refpage='VkRelativePresentTimeEXT',desc='Specifying the minimum duration an image should be presented',type='structs'] +-- + +The sname:VkRelativePresentTimeEXT structure is defined as: + +include::{generated}/api/structs/VkRelativePresentTimeEXT.txt[] + + * pname:presentID is an application-provided identification value. + If non-zero, flink:vkGetPastPresentationTimingEXT will return a + slink:VkPastPresentationTimingEXT struct with the timing information + associated with the present to the associated swapchain for this + call to flink:vkQueuePresentKHR, including this value being in the + pname:presentID member of the slink:VkPastPresentationTimingEXT + struct. + In order to be useful to the application, it should: be unique within + some period of time that is meaningful to the application. + * pname:minPresentDuration, if non-zero, specifies the minimum duration + in nanoseconds the application wants the image to be displayed to the + user. + A value of zero specifies that the presentation engine may: display the + image for any duration. + * pname:idealPresentDuration provides an indication to the presentation + engine of what the application desires its IPD to become. + An application can: set pname:idealPresentDuration to the same value + as pname:minPresentDuration, indicating that the application + desires its IPD to remain steady. + A value smaller than + pname:minPresentDuration indicates that the application desires to + shorten its IPD. + A value larger than pname:minPresentDuration + indicates that the application desires to lengthen its IPD. + The presentation engine will provide feedback on this value in the + data returned by flink:vkGetPastPresentationTimingEXT. + * pname:presentSlop is the period of time in nanoseconds before + pname:minPresentDuration elapses that the presentation engine may: + display the image. + +If pname:minPresentDuration is non-zero, the presentation engine should: +display the image to the user for a minimum duration of +(pname:minPresentDuration - pname:presentSlop) nanoseconds. + +Setting pname:minPresentDuration to zero is useful when the application +desires to provide a non-zero pname:presentID in order to get back timing +information from flink:vkGetPastPresentationTimingEXT, but does not wish +to set a pname:minPresentDuration. + +Providing a pname:presentSlop enables the application to indicate to the +presentation engine to display the image within this period if a vertical +blanking period occurs on FRR displays. + +[NOTE] +.Note +==== +The pname:presentSlop is used to avoid unintentionally missing a vertical +blanking period on FRR displays due to rounding errors or drift between +clocks. +A suggested value for pname:presentSlop is half the _Refresh Rate_. +==== + +include::{generated}/validity/structs/VkRelativePresentTimeEXT.txt[] + +-- diff --git a/chapters/VK_EXT_present_timing/queries.txt b/chapters/VK_EXT_present_timing/queries.txt new file mode 100644 index 0000000000..c93764e8ee --- /dev/null +++ b/chapters/VK_EXT_present_timing/queries.txt @@ -0,0 +1,441 @@ +// Copyright (c) 2014-2020 Khronos Group. +// +// SPDX-License-Identifier: CC-BY-4.0 + +== Present/Display Timing Queries + +Traditional game and real-time-animation applications frequently use +ename:VK_PRESENT_MODE_FIFO_KHR so that presentable images are updated during +the vertical blanking period of a given refresh cycle (RC) of the +presentation engine's display. +This avoids the visual anomaly known as tearing. + +However, synchronizing the presentation of images with the RC does not +prevent all forms of visual anomalies. +Stuttering occurs when the geometry for each presentable image isn't +accurately positioned for when that image will be displayed. +The geometry may appear to move too little some RCs, and too much for +others. +Sometimes the animation appears to freeze, when the same image is used for +more than one RC. + +In order to minimize stuttering, an application needs to: 1) render +and present images at a consistent rate that is a multiple of the +presentation engine's refresh rate; 2) correctly position its geometry +for when the presentable image will be displayed to the user. +Applications can: benefit from communication of timing information with the +presentation engine and its display. +For example, applications can: determine information about the refresh +rate of the display/compositor, can: specify when an image should be +presented, and can: determine when an image was actually presented. +This can allow the application's animation to look smooth to the user, with +no stuttering. +The +ifdef::VK_EXT_present_timing+VK_GOOGLE_display_timing[] +`VK_EXT_present_timing` and `VK_GOOGLE_display_timing` extensions allow +endif::VK_EXT_present_timing+VK_GOOGLE_display_timing[] +ifdef::VK_EXT_present_timing[] +`VK_EXT_present_timing` extension allows +endif::VK_EXT_present_timing[] +ifdef::VK_GOOGLE_display_timing[] +`VK_GOOGLE_display_timing` extension allows +endif::VK_GOOGLE_display_timing[] +an application to satisfy these needs. + +The presentation engine's display typically refreshes the pixels that are +displayed to the user on a periodic basis. +The period may be fixed or variable. +In many cases, the presentation engine is associated with fixed refresh rate +(FRR) display technology, with a fixed refresh rate (RR, e.g. 60Hz). +In some cases, the presentation engine is associated with variable refresh +rate (VRR) display technology, where each refresh cycle (RC) can vary in +length. + +ifdef::VK_EXT_present_timing[] +[open,refpage='vkGetSwapchainTimingPropertiesEXT',desc='Obtain the display timing properties of the PE\'s display',type='protos'] +-- + +To query the presentation engine's timing properties for a given swapchain, +call: + +include::{generated}/api/protos/vkGetSwapchainTimingPropertiesEXT.txt[] + + * pname:device is the device associated with pname:swapchain. + * pname:swapchain is the swapchain to obtain timing properties for. + * pname:pSwapchainTimingProperties is a pointer to an instance of the + sname:VkSwapchainTimingPropertiesEXT structure. + +include::{generated}/validity/protos/vkGetSwapchainTimingPropertiesEXT.txt[] +-- + +[open,refpage='VkSwapchainTimingPropertiesEXT',desc='Structure containing the RC duration of a display',type='structs'] +-- + +The sname:VkSwapchainTimingPropertiesEXT structure is defined as: + +include::{generated}/api/structs/VkSwapchainTimingPropertiesEXT.txt[] + + * pname:sType is the type of this structure. + * pname:pNext is `NULL` or a pointer to an extension-specific structure. + * pname:refreshDuration is zero; or is an indication of the duration + of a refresh cycle. + If the presentation engine is operating as an FRR display, this is the + number of nanoseconds from the start of one refresh cycle to the + start of the next refresh cycle. + If the presentation engine is operating as an VRR display + (i.e. refresh cycles may: have variable length), this is the + minimum number of nanoseconds from the start of one refresh cycle + to the start of the next refresh cycle. + * pname:variableRefresh is undefined: if pname:refreshDuration is + zero; otherwise it is ename:VK_FALSE if the presentation engine is + operating as a FRR display, or ename:VK_TRUE if the presentation + engine is operating as a VRR display. + +include::{generated}/validity/structs/VkSwapchainTimingPropertiesEXT.txt[] + +Some platforms (e.g. Wayland) may: not provide timing properties until +after at least one image has been presented to the pname:swapchain. +If timing properties change for the pname:swapchain, these same +platforms may: not provide updated results until after at least one +additional image has been presented to the pname:swapchain. + + +-- + +[NOTE] +.Note +==== +The rate at which an application renders and presents new images is known as +the image present rate (IPR, a.k.a. frame rate). +The inverse of IPR, or the duration between each image present, is the image +present duration (IPD). +In order to provide a smooth, stutter-free animation, an application needs +its IPD to be a multiple of pname:refreshDuration. +For example, if a display has a 60Hz refresh rate, pname:refreshDuration +will be a value in nanoseconds that is approximately equal to 16.67ms. +In such a case, an application will want an IPD of 16.67ms (1X multiplier of +pname:refreshDuration), or 33.33ms (2X multiplier of pname:refreshDuration), +or 50.0ms (3X multiplier of pname:refreshDuration), etc. + +In order to determine a target IPD for a display (i.e. a multiple of +pname:refreshDuration), an application needs to determine when its images +are actually displayed. +Let's say that an application has an initial target IPD of 16.67ms (1X +multiplier of pname:refreshDuration). +It will therefore position the geometry of a new image 16.67ms later than +the previous image. +Let's say that this application is running on slower hardware, so that it +actually takes 20ms to render each new image. +This will create visual anomalies, because the images won't be displayed to +the user every 16.67ms, nor every 20ms. +In this case, it is better for the application to adjust its target IPD to +33.33ms (i.e. a 2X multiplier of pname:refreshDuration), and tell the +presentation engine to not present images any sooner than every 33.33ms. +This will allow the geometry to be correctly positioned for each presentable +image. + +Adjustments to an application's IPD may be needed because different views of +an application's geometry can take different amounts of time to render. +For example, looking at the sky may take less time to render than looking at +multiple, complex items in a room. +In general, it is good to not frequently change IPD, as that can cause +visual anomalies. +Adjustments to a larger IPD because of late images should happen quickly, +but adjustments to a smaller IPD should only happen if the +pname:optimalPresentTime member of the +slink:VkPastPresentationTimingEXT structure is consistently the same as the +pname:idealPresentTime member of the +slink:VkPresentTimeEXT structure over multiple images. +==== + +[open,refpage='vkGetSwapchainTimeDomainsEXT',desc='Obtain the time domain used by the PE for the swapchain',type='protos'] +-- + +To query the time domain used by the presentation engine for a given swapchain, +call: + +include::{generated}/api/protos/vkGetSwapchainTimeDomainsEXT.txt[] + + * pname:device is the device associated with pname:swapchain. + * pname:swapchain is the swapchain to obtain timing properties for. + * pname:pSwapchainTimeDomainCount is a pointer to an integer related to the + number of time domains available or queried, as described below. + * pname:pSwapchainTimeDomains is either `NULL` or a pointer to an array of + slink:VkSwapchainTimeDomainPropertiesEXT structs, indicating the supported time + domains of the presentation engine for the swapchain. + +If pname:pSwapchainTimeDomains is `NULL`, then the number of time domains +supported for the given pname:swapchain is returned in +pname:pSwapchainTimeDomainCount (if this value is zero, pname:swapchain +does not currently support display timing). +Otherwise, pname:pSwapchainTimeDomainCount must: point to a variable set by the user +to the number of elements in the pname:pSwapchainTimeDomains array, and on return +the variable is overwritten with the number of values actually written to +pname:pSwapchainTimeDomains. +If the value of pname:pSwapchainTimeDomainCount is less than the number of +time domains supported, at most pname:pSwapchainTimeDomainCount values will be +written. +If pname:pSwapchainTimeDomainCount is smaller than the number of time domains +supported for the given pname:swapchain, ename:VK_INCOMPLETE will be returned +instead of ename:VK_SUCCESS to indicate that not all the available values +were returned. + +include::{generated}/validity/protos/vkGetSwapchainTimeDomainsEXT.txt[] +-- + +[open,refpage='VkSwapchainTimeDomainPropertiesEXT',desc='An available time domain for a swapchain',type='structs'] +-- + +The sname:VkSwapchainTimeDomainPropertiesEXT structure is defined as: + +include::{generated}/api/structs/VkSwapchainTimeDomainPropertiesEXT.txt[] + + * pname:sType is the type of this structure. + * pname:pNext is `NULL` or a pointer to an extension-specific structure. + * pname:timeDomain is a elink:VkTimeDomainEXT value representing a time + domain that is available for the swapchain. + +include::{generated}/validity/structs/VkSwapchainTimeDomainPropertiesEXT.txt[] +-- + +[open,refpage='vkSetSwapchainTimingEXT',desc='Set timing information for a swapchain',type='protos'] +-- + +To set timing information for a swapchain, call: + +include::{generated}/api/protos/vkSetSwapchainTimingEXT.txt[] + + * pname:device is the device associated with pname:swapchain. + * pname:swapchain is the swapchain to obtain timing properties for. + * pname:pSwapchainTimingInfo is `NULL` or a pointer to an instance of + the sname:VkSwapchainTimingInfoEXT structure. If `NULL`, + display timing is disabled for the swapchain, otherwise enables + display timing and specifies which time domain to use. + +include::{generated}/validity/protos/vkSetSwapchainTimingEXT.txt[] +-- + +[open,refpage='VkSwapchainTimingInfoEXT',desc='Specify which of the available time domains to use for a swapchain',type='structs'] +-- + +The sname:VkSwapchainTimingInfoEXT structure is defined as: + +include::{generated}/api/structs/VkSwapchainTimingInfoEXT.txt[] + + * pname:sType is the type of this structure. + * pname:pNext is `NULL` or a pointer to an extension-specific structure. + * pname:timeDomain is a elink:VkTimeDomainEXT value representing the time + domain that should be used with the swapchain. + +include::{generated}/validity/structs/VkSwapchainTimingInfoEXT.txt[] + +-- + +[open,refpage='vkGetPastPresentationTimingEXT',desc='Obtain timing of a previously-presented image',type='protos'] +-- + +The implementation will maintain a limited amount of history of timing +information about previous presents. +Because of the asynchronous nature of the presentation engine, the timing +information for a given flink:vkQueuePresentKHR command will become +available some time later. +These time values can be asynchronously queried, and will be returned if +available. +All time values are in nanoseconds, according to the time-domain being used. + +To asynchronously query the presentation engine, for newly-available timing +information about one or more previous presents to a given swapchain, call: + +include::{generated}/api/protos/vkGetPastPresentationTimingEXT.txt[] + + * pname:device is the device associated with pname:swapchain. + * pname:swapchain is the swapchain to obtain presentation timing + information duration for. + * pname:pPresentationTimingCount is a pointer to an integer related to the + number of sname:VkPastPresentationTimingEXT structures to query, as + described below. + * pname:pPresentationTimings is either `NULL` or a pointer to an an array + of sname:VkPastPresentationTimingEXT structures. + +If pname:pPresentationTimings is `NULL`, then the number of newly-available +timing records for the given pname:swapchain is returned in +pname:pPresentationTimingCount. +Otherwise, pname:pPresentationTimingCount must: point to a variable set by +the user to the number of elements in the pname:pPresentationTimings array, +and on return the variable is overwritten with the number of structures +actually written to pname:pPresentationTimings. +If the value of pname:pPresentationTimingCount is less than the number of +newly-available timing records, at most pname:pPresentationTimingCount +structures will be written. +If pname:pPresentationTimingCount is smaller than the number of +newly-available timing records for the given pname:swapchain, +ename:VK_INCOMPLETE will be returned instead of ename:VK_SUCCESS to indicate +that not all the available values were returned. + +include::{generated}/validity/protos/vkGetPastPresentationTimingEXT.txt[] +-- + +[open,refpage='VkPastPresentationTimingEXT',desc='Structure containing timing information about a previously-presented image',type='structs'] +-- + +The sname:VkPastPresentationTimingEXT structure is defined as: + +include::{generated}/api/structs/VkPastPresentationTimingEXT.txt[] + + * pname:sType is the type of this structure. + * pname:pNext is `NULL` or a pointer to an extension-specific structure. + * pname:presentID is an application-provided value that was given to a + previous fname:vkQueuePresentKHR command via + slink:VkPresentTimeEXT::pname:presentID. + It can: be used to uniquely identify a previous present with the + flink:vkQueuePresentKHR command. + * pname:targetPresentTime is an application-provided value that was given + to a previous flink:vkQueuePresentKHR command via + slink:VkPresentTimeEXT::pname:targetPresentTime. + If non-zero, it was used by the application to indicate that an image + not be presented any sooner than pname:targetPresentTime. + * pname:actualPresentTime is the time when the image of the + pname:swapchain was actually displayed. + * pname:optimalPresentTime is the time when the presentation engine (PE) + would have liked the application to have set pname:targetPresentTime to. + This allows the PE to provide feedback to the application-provided + slink:VkPresentTimeEXT::pname:idealPresentTime. + The PE may: set this to pname:actualPresentTime, to + slink:VkPresentTimeEXT::pname:idealPresentTime, or to some other + time based upon how the application is performing, the system load + and/or future clock settings, etc. + * pname:timingPropertiesChanged is ename:VK_TRUE if the swapchain's + timing properties have changed since the last time those + properties were queried with + flink:vkGetSwapchainTimingPropertiesEXT, otherwise the properties + have not changed. + If ename:VK_TRUE, an application must: not compare the values of + pname:actualPresentTime and pname:optimalPresentTime with any + other values, as the pname:presentation engine may not be able to + provide accurate values. + * pname:timeDomainChanged is ename:VK_TRUE if the time domain enabled for + the swapchain is not currently available. + The application must: query what time domains are available and + enable display timing with a currently-available time domain. + If the currently-enabled time domain is the opaque domain of + ename:VK_TIME_DOMAIN_SWAPCHAIN_LOCAL_EXT, it is possible that + ename:VK_TIME_DOMAIN_SWAPCHAIN_LOCAL_EXT will be returned by + flink:vkGetSwapchainTimeDomainsEXT. + In such a case, the presentation engine may: have multiple opaque + time domains that it is switching between. + If ename:VK_TRUE, an application must: not compare the values of + pname:actualPresentTime and pname:optimalPresentTime with any + other values, as the pname:presentation engine may not be able to + provide accurate values. + +include::{generated}/validity/structs/VkPastPresentationTimingEXT.txt[] + +The results for a given pname:swapchain and pname:presentID are only +returned once from fname:vkGetPastPresentationTimingEXT. + +The application can: use the sname:VkPastPresentationTimingEXT values to +occasionally adjust its timing. + +An example is in order. +If the system has a 60Hz FRR, and if the application’s IPD is +currently 16.67ms (i.e. 60FPS), the application will set both +slink:VkPresentTimeEXT::pname:targetPresentTime and +slink:VkPresentTimeEXT::pname:idealPresentTime to 16.67ms after the +same values that were used for the previous image. +If sname:VkPastPresentationTimingEXT::pname:actualPresentTime and +sname:VkPastPresentationTimingEXT::pname:targetPresentTime are +approximately equal to each other (e.g. less than 1ms different), +and if this is the case for many consecutive images, +the application knows that it is rendering smooth, and with no stutter. +If sname:VkPastPresentationTimingEXT::pname:actualPresentTime is +approximately 16.67 later than +sname:VkPastPresentationTimingEXT::pname:targetPresentTime, +the application knows that the image was presented late. +The application can: then change the IPD to 33.33ms (i.e. 30FPS). +It does this by setting both +slink:VkPresentTimeEXT::pname:targetPresentTime and +slink:VkPresentTimeEXT::pname:idealPresentTime to 33.33ms after the +same values that were used for the previous image. + +Later, if the application has been consistently presenting images on +time with an IPD of 33.33ms, if the application desires to try an IPD +of 16.67ms, it can: determine whether it is safe to do so. +It does this by setting slink:VkPresentTimeEXT::pname:idealPresentTime +to 16.67ms earlier than +slink:VkPresentTimeEXT::pname:targetPresentTime, which will continue +to be set to 33.33ms after the +slink:VkPresentTimeEXT::pname:targetPresentTime of the the previous +image. +In this way, the application continues to present images stutter-free, +while requesting feedback from the PE as to whether it can still be +stutter-free with an IPD of 16.67ms. +If the PE determines that it could have displayed the image at +slink:VkPresentTimeEXT::pname:idealPresentTime, it will set +pname:optimalPresentTime to +slink:VkPresentTimeEXT::pname:idealPresentTime. +If so, the application knows it is safe to change its IPD to 16.67ms. + +[NOTE] +.Note +==== +Frequent changes to an application's IPD can cause visual artifacts. +Therefore, it is wise for an application to avoid frequent changes to +its IPD. +In the above example, before an application decreases its IPD, it will +want to see several consecutive images all have +pname:optimalPresentTime equal to +slink:VkPresentTimeEXT::pname:idealPresentTime. +==== + +[NOTE] +.Note +==== +The presentation engine may change the timing properties of the +pname:swapchain for a variety of reasons. +For example, if the window system changes its mode, including the +refresh rate of the display. +Another example is if an application's surface is being composited +with other windows of a window system, and then the surface's window +becomes a borderless, full-screen window. +While composited, the timing properties may be 60Hz FRR, and while +full-screen, the timing properties may be VRR. + +The available time domains for a swapchain may change for similar or +identical reasons. +Therefore, it is possible that the same event will cause both +pname:timingPropertiesChanged and pname:timeDomainChanged to become +ename:VK_TRUE. +It is also possible that an event can cause only +pname:timingPropertiesChanged to become ename:VK_TRUE. +==== + +-- + +The full `VK_EXT_present_timing` extension semantics are only described for +swapchains created with the following present modes: + + * ename:VK_PRESENT_MODE_FIFO_KHR. + Tearing cannot be observed. + The first queued image is dequeued and presented if + both: 1) its associated wait semaphore(s) have signaled, and 2) + its target present time is less-than or equal-to the current time. + * ename:VK_PRESENT_MODE_FIFO_RELAXED_KHR. + For images that are presented in time to be displayed at the next + vertical blanking period, the semantics are identical as for + ename:VK_PRESENT_MODE_FIFO_RELAXED_KHR. + For images that are presented late, and are displayed after the start of + the vertical blanking period (i.e. with tearing), the values of + sname:VkPastPresentationTimingEXT may: be treated as if the image was + displayed at the start of the vertical blanking period, or may: be + treated the same as for ename:VK_PRESENT_MODE_IMMEDIATE_KHR. + * ename:VK_PRESENT_MODE_FIFO_LATEST_READY_EXT. + Tearing cannot be observed. + Starting in queue order, successive images are dequeued when both: + 1) its associated wait semaphore(s) have signaled, and 2) its + target present time is less-than or equal-to the current time. + The last of the successive images that are dequeued is presented. +endif::VK_EXT_present_timing[] + +ifdef::VK_GOOGLE_display_timing[] +include::../VK_GOOGLE_display_timing/queries.txt[] +endif::VK_GOOGLE_display_timing[] diff --git a/chapters/VK_GOOGLE_display_timing/queries.txt b/chapters/VK_GOOGLE_display_timing/queries.txt index 7360705360..1b823a0b2e 100644 --- a/chapters/VK_GOOGLE_display_timing/queries.txt +++ b/chapters/VK_GOOGLE_display_timing/queries.txt @@ -2,45 +2,6 @@ // // SPDX-License-Identifier: CC-BY-4.0 -== Display Timing Queries - -Traditional game and real-time-animation applications frequently use -ename:VK_PRESENT_MODE_FIFO_KHR so that presentable images are updated during -the vertical blanking period of a given refresh cycle (RC) of the -presentation engine's display. -This avoids the visual anomaly known as tearing. - -However, synchronizing the presentation of images with the RC does not -prevent all forms of visual anomalies. -Stuttering occurs when the geometry for each presentable image is not -accurately positioned for when that image will be displayed. -The geometry may appear to move too little some RCs, and too much for -others. -Sometimes the animation appears to freeze, when the same image is used for -more than one RC. - -In order to minimize stuttering, an application needs to correctly position -their geometry for when the presentable image will be displayed to the user. -To accomplish this, applications need various timing information about the -presentation engine's display. -They need to know when presentable images were actually presented, and when -they could have been presented. -Applications also need to tell the presentation engine to display an image -no sooner than a given time. -This can allow the application's animation to look smooth to the user, with -no stuttering. -The `VK_GOOGLE_display_timing` extension allows an application to satisfy -these needs. - -The presentation engine's display typically refreshes the pixels that are -displayed to the user on a periodic basis. -The period may be fixed or variable. -In many cases, the presentation engine is associated with fixed refresh rate -(FRR) display technology, with a fixed refresh rate (RR, e.g. 60Hz). -In some cases, the presentation engine is associated with variable refresh -rate (VRR) display technology, where each refresh cycle (RC) can vary in -length. -This extension treats VRR displays as if they are FRR. [open,refpage='vkGetRefreshCycleDurationGOOGLE',desc='Obtain the RC duration of the PE\'s display',type='protos'] -- @@ -72,51 +33,6 @@ include::{generated}/validity/structs/VkRefreshCycleDurationGOOGLE.txt[] -- -[NOTE] -.Note -==== -The rate at which an application renders and presents new images is known as -the image present rate (IPR, aka frame rate). -The inverse of IPR, or the duration between each image present, is the image -present duration (IPD). -In order to provide a smooth, stutter-free animation, an application will -want its IPD to be a multiple of pname:refreshDuration. -For example, if a display has a 60Hz refresh rate, pname:refreshDuration -will be a value in nanoseconds that is approximately equal to 16.67ms. -In such a case, an application will want an IPD of 16.67ms (1X multiplier of -pname:refreshDuration), or 33.33ms (2X multiplier of pname:refreshDuration), -or 50.0ms (3X multiplier of pname:refreshDuration), etc. - -In order to determine a target IPD for a display (i.e. a multiple of -pname:refreshDuration), an application needs to determine when its images -are actually displayed. -Let's say that an application has an initial target IPD of 16.67ms (1X -multiplier of pname:refreshDuration). -It will therefore position the geometry of a new image 16.67ms later than -the previous image. -Let's say that this application is running on slower hardware, so that it -actually takes 20ms to render each new image. -This will create visual anomalies, because the images will not be displayed -to the user every 16.67ms, nor every 20ms. -In this case, it is better for the application to adjust its target IPD to -33.33ms (i.e. a 2X multiplier of pname:refreshDuration), and tell the -presentation engine to not present images any sooner than every 33.33ms. -This will allow the geometry to be correctly positioned for each presentable -image. - -Adjustments to an application's IPD may be needed because different views of -an application's geometry can take different amounts of time to render. -For example, looking at the sky may take less time to render than looking at -multiple, complex items in a room. -In general, it is good to not frequently change IPD, as that can cause -visual anomalies. -Adjustments to a larger IPD because of late images should happen quickly, -but adjustments to a smaller IPD should only happen if the -pname:actualPresentTime and pname:earliestPresentTime members of the -slink:VkPastPresentationTimingGOOGLE structure are consistently different, -and if pname:presentMargin is consistently large, over multiple images. -==== - [open,refpage='vkGetPastPresentationTimingGOOGLE',desc='Obtain timing of a previously-presented image',type='protos'] -- @@ -255,7 +171,7 @@ The semantics for other present modes are as follows: far enough in the future that an image is not presented before fname:vkQueuePresentKHR is called to present another image, the first image will not be displayed to the user. - If the application continues to do that, the presentation may: not + If the application continues to do that, the presentation engine may: not display new images. * ename:VK_PRESENT_MODE_FIFO_RELAXED_KHR. For images that are presented in time to be displayed at the next diff --git a/chapters/VK_KHR_surface/wsi.txt b/chapters/VK_KHR_surface/wsi.txt index 4a7ecfa61d..b78cdd01e8 100644 --- a/chapters/VK_KHR_surface/wsi.txt +++ b/chapters/VK_KHR_surface/wsi.txt @@ -1207,6 +1207,29 @@ include::{generated}/api/enums/VkPresentModeKHR.txt[] New requests are appended to the end of the queue, and one request is removed from the beginning of the queue and processed during or after each vertical blanking period in which the queue is non-empty. +ifdef::VK_EXT_present_timing[] + * ename:VK_PRESENT_MODE_FIFO_LATEST_READY_EXT specifies that the + presentation engine waits for the next vertical blanking period to + update the current image. + Tearing cannot: be observed. + An internal queue is used to hold pending presentation requests. + New requests are appended to the end of the queue. + At each vertical blanking period, the presentation engine dequeues + successive-queued images for which their associated wait semaphores have + signaled. + The last image dequeued is presented. + The other dequeued images will not be presented, and may: + immediately be returned by flink:vkAcquireNextImageKHR with a + pname:fence and/or pname:semaphore that is already in a signaled + state. + If present timing is enabled for the swapchain, the presentation + engine will also check that the target present time for an image. + If the target present time is less-than or equal-to the current + time, the presentation engine will dequeue the image and check the + next image. + Once the presentation engine doesn't dequeue an image, it stops + checking successive images. +endif::VK_EXT_present_timing[] ifdef::VK_KHR_shared_presentable_image[] * ename:VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR specifies that the presentation engine and application have concurrent access to a single @@ -1531,9 +1554,9 @@ include::{generated}/validity/protos/vkGetPhysicalDevicePresentRectanglesKHR.txt endif::VK_VERSION_1_1,VK_KHR_device_group[] -ifdef::VK_GOOGLE_display_timing[] -include::{chapters}/VK_GOOGLE_display_timing/queries.txt[] -endif::VK_GOOGLE_display_timing[] +ifdef::VK_EXT_present_timing,VK_GOOGLE_display_timing[] +include::../VK_EXT_present_timing/queries.txt[] +endif::VK_EXT_present_timing,VK_GOOGLE_display_timing[] include::{chapters}/VK_KHR_swapchain/wsi.txt[] endif::VK_KHR_swapchain[] diff --git a/chapters/VK_KHR_swapchain/wsi.txt b/chapters/VK_KHR_swapchain/wsi.txt index 5e011f784e..07798e408f 100644 --- a/chapters/VK_KHR_swapchain/wsi.txt +++ b/chapters/VK_KHR_swapchain/wsi.txt @@ -466,6 +466,16 @@ ifdef::VK_KHR_swapchain_mutable_format[] created with but are supported for at least one of the allowed image view formats. endif::VK_KHR_swapchain_mutable_format[] +ifdef::VK_EXT_present_timing[] + * ename:VK_SWAPCHAIN_CREATE_ABSOLUTE_TIME_BIT_EXT specifies that when + images of the swapchain are presented, a + slink:VkAbsolutePresentTimeEXT can: be provided to specify the + absolute time they should: be displayed. + * ename:VK_SWAPCHAIN_CREATE_RELATIVE_TIME_BIT_EXT specifies that when + images of the swapchain are presented, an + slink:VkRelativePresentTimeEXT can: be provided to specify the + minimum duration they should: be displayed. +endif::VK_EXT_present_timing[] -- @@ -1417,6 +1427,9 @@ include::{generated}/validity/structs/VkDeviceGroupPresentInfoKHR.txt[] endif::VK_VERSION_1_1,VK_KHR_device_group[] +ifdef::VK_EXT_present_timing[] +include::../VK_EXT_present_timing/PresentTimeInfo.txt[] +endif::VK_EXT_present_timing[] ifdef::VK_GOOGLE_display_timing[] include::{chapters}/VK_GOOGLE_display_timing/PresentTimeInfo.txt[] endif::VK_GOOGLE_display_timing[] diff --git a/chapters/synchronization.txt b/chapters/synchronization.txt index 879d8f809e..1982aaa7de 100644 --- a/chapters/synchronization.txt +++ b/chapters/synchronization.txt @@ -4811,6 +4811,13 @@ include::{generated}/api/enums/VkTimeDomainEXT.txt[] flink:vkCmdWriteTimestamp and are defined to be incrementing according to the <> of the device. +ifdef::VK_EXT_present_timing[] + * ename:VK_TIME_DOMAIN_SWAPCHAIN_LOCAL_EXT specifies a time domain unique + to a particular swapchain. + Timestamp values in this time domain are in units of nanosecond and are + comparable only with other values from the same swapchain. +endif::VK_EXT_present_timing[] + * ename:VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT specifies the CLOCK_MONOTONIC time domain available on POSIX platforms. Timestamp values in this time domain are in units of nanoseconds and are diff --git a/xml/vk.xml b/xml/vk.xml index 2c5b128f6a..81c96111f9 100644 --- a/xml/vk.xml +++ b/xml/vk.xml @@ -2568,6 +2568,55 @@ typedef void CAMetalLayer; float x float y + + VkStructureType sType + const void* pNext + uint64_t refreshDurationNumber of nanoseconds from the start of one refresh cycle to the next + VkBool32 variableRefresh + + + VkStructureType sType + void* pNext + VkTimeDomainEXT timeDomainAvailable time domain to use with the swapchain + + + VkStructureType sType + const void* pNext + VkTimeDomainEXT timeDomainAvailable time domain to use with the swapchain + + + VkStructureType sType + void* pNext + uint32_t presentIDApplication-provided identifier, previously given to vkQueuePresentKHR + uint64_t targetPresentTimeEarliest time an image should have been presented, previously given to vkQueuePresentKHR + uint64_t actualPresentTimeTime the image was actually displayed + uint64_t optimalPresentTimeTime when the PE would have liked the application to have set targetPresentTime to + VkBool32 timingPropertiesChangedVK_TRUE if swapchain's timing properties changed since last queried + VkBool32 timeDomainChangedVK_TRUE if the swapchain no longer supports the enabled time domain + + + VkStructureType sType + const void* pNext + uint32_t swapchainCountCopy of VkPresentInfoKHR::swapchainCount + const VkPresentTimeEXT* pTimesWhen to present images + + + uint32_t presentIDApplication-provided identifier + uint64_t targetPresentTimeEarliest time an image should be presented + uint64_t idealPresentTimeIndication to PE of what the application would like targetPresentTime to have been + uint64_t presentSlopPeriod of time an image may be presented before targetPresentTime + + + uint32_t presentIDApplication-provided identifier + uint64_t minPresentDurationShortest duration an image should be presented + uint64_t idealPresentDurationIndication to PE of what the application would like minPresentDuration to be + uint64_t presentSlopPeriod of time an image may be presented before minPresentDuration elapses + + + VkAbsolutePresentTimeEXT absolutePresentTime + VkRelativePresentTimeEXT relativePresentTime + + Display primary in chromaticity coordinates VkStructureType sType @@ -7490,6 +7539,12 @@ typedef void CAMetalLayer; VkQueue queue const VkPresentInfoKHR* pPresentInfo + + VkResult vkSetSwapchainTimingEXT + VkDevice device + VkSwapchainKHR swapchain + const VkSwapchainTimingInfoEXT* pSwapchainTimingInfo + VkResult vkCreateViSurfaceNN VkInstance instance @@ -7988,6 +8043,13 @@ typedef void CAMetalLayer; uint32_t set const void* pData + + VkResult vkGetPastPresentationTimingEXT + VkDevice device + VkSwapchainKHR swapchain + uint32_t* pPresentationTimingCount + VkPastPresentationTimingEXT* pPresentationTimings + void vkSetHdrMetadataEXT VkDevice device @@ -9071,6 +9133,19 @@ typedef void CAMetalLayer; VkCommandBuffer commandBuffer const VkResolveImageInfo2KHR* pResolveImageInfo + + VkResult vkGetSwapchainTimingPropertiesEXT + VkDevice device + VkSwapchainKHR swapchain + VkSwapchainTimingPropertiesEXT* pSwapchainTimingProperties + + + VkResult vkGetSwapchainTimeDomainsEXT + VkDevice device + VkSwapchainKHR swapchain + uint32_t* pSwapchainTimeDomainCount + VkSwapchainTimeDomainPropertiesEXT* pSwapchainTimeDomains + @@ -12832,10 +12907,31 @@ typedef void CAMetalLayer; - - - - + + + + + + + + + + + + + + + + + + + + + + + + +