mirror of
https://gitlab.freedesktop.org/mesa/vulkan-wsi-layer.git
synced 2025-12-20 06:50:08 +01:00
Update present timing types
Updates the present timing implementation and types to be aligned with the latest commit. Fixes an issue, where the queue used for the presentation feedback events was destroyed before getting the last events. Signed-off-by: Iason Paraskevopoulos <iason.paraskevopoulos@arm.com> Change-Id: I1dba2fd0e4ad9ec8c02d71c58c93edceaa75d07e
This commit is contained in:
parent
6baf6ff52a
commit
b02e682d30
11 changed files with 84 additions and 85 deletions
|
|
@ -60,16 +60,16 @@ wsi_layer_vkSetSwapchainPresentTimingQueueSizeEXT(VkDevice device, VkSwapchainKH
|
||||||
*/
|
*/
|
||||||
VWL_VKAPI_CALL(VkResult)
|
VWL_VKAPI_CALL(VkResult)
|
||||||
wsi_layer_vkGetSwapchainTimingPropertiesEXT(VkDevice device, VkSwapchainKHR swapchain,
|
wsi_layer_vkGetSwapchainTimingPropertiesEXT(VkDevice device, VkSwapchainKHR swapchain,
|
||||||
uint64_t *pSwapchainTimingPropertiesCounter,
|
VkSwapchainTimingPropertiesEXT *pSwapchainTimingProperties,
|
||||||
VkSwapchainTimingPropertiesEXT *pSwapchainTimingProperties) VWL_API_POST
|
uint64_t *pSwapchainTimingPropertiesCounter) VWL_API_POST
|
||||||
{
|
{
|
||||||
assert(swapchain != VK_NULL_HANDLE);
|
assert(swapchain != VK_NULL_HANDLE);
|
||||||
|
|
||||||
auto &device_data = layer::device_private_data::get(device);
|
auto &device_data = layer::device_private_data::get(device);
|
||||||
if (!device_data.layer_owns_swapchain(swapchain))
|
if (!device_data.layer_owns_swapchain(swapchain))
|
||||||
{
|
{
|
||||||
return device_data.disp.GetSwapchainTimingPropertiesEXT(device, swapchain, pSwapchainTimingPropertiesCounter,
|
return device_data.disp.GetSwapchainTimingPropertiesEXT(device, swapchain, pSwapchainTimingProperties,
|
||||||
pSwapchainTimingProperties);
|
pSwapchainTimingPropertiesCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *sc = reinterpret_cast<wsi::swapchain_base *>(swapchain);
|
auto *sc = reinterpret_cast<wsi::swapchain_base *>(swapchain);
|
||||||
|
|
@ -82,16 +82,16 @@ wsi_layer_vkGetSwapchainTimingPropertiesEXT(VkDevice device, VkSwapchainKHR swap
|
||||||
* @brief Implements vkGetSwapchainTimeDomainPropertiesEXT Vulkan entrypoint.
|
* @brief Implements vkGetSwapchainTimeDomainPropertiesEXT Vulkan entrypoint.
|
||||||
*/
|
*/
|
||||||
VWL_VKAPI_CALL(VkResult)
|
VWL_VKAPI_CALL(VkResult)
|
||||||
wsi_layer_vkGetSwapchainTimeDomainPropertiesEXT(
|
wsi_layer_vkGetSwapchainTimeDomainPropertiesEXT(VkDevice device, VkSwapchainKHR swapchain,
|
||||||
VkDevice device, VkSwapchainKHR swapchain, uint64_t *pTimeDomainsCounter,
|
VkSwapchainTimeDomainPropertiesEXT *pSwapchainTimeDomainProperties,
|
||||||
VkSwapchainTimeDomainPropertiesEXT *pSwapchainTimeDomainProperties) VWL_API_POST
|
uint64_t *pTimeDomainsCounter) VWL_API_POST
|
||||||
{
|
{
|
||||||
auto &device_data = layer::device_private_data::get(device);
|
auto &device_data = layer::device_private_data::get(device);
|
||||||
|
|
||||||
if (!device_data.layer_owns_swapchain(swapchain))
|
if (!device_data.layer_owns_swapchain(swapchain))
|
||||||
{
|
{
|
||||||
return device_data.disp.GetSwapchainTimeDomainPropertiesEXT(device, swapchain, pTimeDomainsCounter,
|
return device_data.disp.GetSwapchainTimeDomainPropertiesEXT(device, swapchain, pSwapchainTimeDomainProperties,
|
||||||
pSwapchainTimeDomainProperties);
|
pTimeDomainsCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *sc = reinterpret_cast<wsi::swapchain_base *>(swapchain);
|
auto *sc = reinterpret_cast<wsi::swapchain_base *>(swapchain);
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@
|
||||||
#define VK_SWAPCHAIN_CREATE_PRESENT_TIMING_BIT_EXT ((VkSwapchainCreateFlagsKHR)0x00010000)
|
#define VK_SWAPCHAIN_CREATE_PRESENT_TIMING_BIT_EXT ((VkSwapchainCreateFlagsKHR)0x00010000)
|
||||||
|
|
||||||
typedef VkFlags VkPresentStageFlagsEXT;
|
typedef VkFlags VkPresentStageFlagsEXT;
|
||||||
|
typedef VkFlags VkPresentTimingInfoFlagsEXT;
|
||||||
|
|
||||||
typedef struct VkPhysicalDevicePresentTimingFeaturesEXT
|
typedef struct VkPhysicalDevicePresentTimingFeaturesEXT
|
||||||
{
|
{
|
||||||
|
|
@ -72,13 +73,12 @@ typedef struct VkPresentTimingSurfaceCapabilitiesEXT
|
||||||
VkBool32 presentAtAbsoluteTimeSupported;
|
VkBool32 presentAtAbsoluteTimeSupported;
|
||||||
VkBool32 presentAtRelativeTimeSupported;
|
VkBool32 presentAtRelativeTimeSupported;
|
||||||
VkPresentStageFlagsEXT presentStageQueries;
|
VkPresentStageFlagsEXT presentStageQueries;
|
||||||
VkPresentStageFlagsEXT presentStageTargets;
|
|
||||||
} VkPresentTimingSurfaceCapabilitiesEXT;
|
} VkPresentTimingSurfaceCapabilitiesEXT;
|
||||||
|
|
||||||
typedef enum VkPresentStageFlagBitsEXT
|
typedef enum VkPresentStageFlagBitsEXT
|
||||||
{
|
{
|
||||||
VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT = 0x00000001,
|
VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT = 0x00000001,
|
||||||
VK_PRESENT_STAGE_IMAGE_LATCHED_BIT_EXT = 0x00000002,
|
VK_PRESENT_STAGE_REQUEST_DEQUEUED_BIT_EXT = 0x00000002,
|
||||||
VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT = 0x00000004,
|
VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT = 0x00000004,
|
||||||
VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_BIT_EXT = 0x00000008,
|
VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_BIT_EXT = 0x00000008,
|
||||||
} VkPresentStageFlagBitsEXT;
|
} VkPresentStageFlagBitsEXT;
|
||||||
|
|
@ -88,7 +88,7 @@ typedef struct VkSwapchainTimingPropertiesEXT
|
||||||
VkStructureType sType;
|
VkStructureType sType;
|
||||||
const void *pNext;
|
const void *pNext;
|
||||||
uint64_t refreshDuration;
|
uint64_t refreshDuration;
|
||||||
uint64_t variableRefreshDelay;
|
uint64_t refreshInterval;
|
||||||
} VkSwapchainTimingPropertiesEXT;
|
} VkSwapchainTimingPropertiesEXT;
|
||||||
|
|
||||||
typedef struct VkSwapchainTimeDomainPropertiesEXT
|
typedef struct VkSwapchainTimeDomainPropertiesEXT
|
||||||
|
|
@ -118,11 +118,12 @@ typedef struct VkPresentStageTimeEXT
|
||||||
typedef struct VkPastPresentationTimingEXT
|
typedef struct VkPastPresentationTimingEXT
|
||||||
{
|
{
|
||||||
VkStructureType sType;
|
VkStructureType sType;
|
||||||
const void *pNext;
|
void *pNext;
|
||||||
uint64_t presentId;
|
uint64_t presentId;
|
||||||
|
uint64_t targetTime;
|
||||||
uint32_t presentStageCount;
|
uint32_t presentStageCount;
|
||||||
VkPresentStageTimeEXT *pPresentStages;
|
VkPresentStageTimeEXT *pPresentStages;
|
||||||
VkTimeDomainEXT timeDomain;
|
VkTimeDomainKHR timeDomain;
|
||||||
uint64_t timeDomainId;
|
uint64_t timeDomainId;
|
||||||
VkBool32 reportComplete;
|
VkBool32 reportComplete;
|
||||||
} VkPastPresentationTimingEXT;
|
} VkPastPresentationTimingEXT;
|
||||||
|
|
@ -145,6 +146,12 @@ typedef enum VkPastPresentationTimingFlagBitsEXT
|
||||||
VK_PAST_PRESENTATION_TIMING_ALLOW_OUT_OF_ORDER_RESULTS_BIT_EXT = 0x00000002,
|
VK_PAST_PRESENTATION_TIMING_ALLOW_OUT_OF_ORDER_RESULTS_BIT_EXT = 0x00000002,
|
||||||
} VkPastPresentationTimingFlagBitsEXT;
|
} VkPastPresentationTimingFlagBitsEXT;
|
||||||
|
|
||||||
|
typedef enum VkPresentTimingInfoFlagBitsEXT
|
||||||
|
{
|
||||||
|
VK_PRESENT_TIMING_INFO_PRESENT_AT_RELATIVE_TIME_BIT_EXT = 0x00000001,
|
||||||
|
VK_PRESENT_TIMING_INFO_PRESENT_AT_NEAREST_REFRESH_CYCLE_BIT_EXT = 0x00000002,
|
||||||
|
} VkPresentTimingInfoFlagBitsEXT;
|
||||||
|
|
||||||
typedef struct VkPastPresentationTimingInfoEXT
|
typedef struct VkPastPresentationTimingInfoEXT
|
||||||
{
|
{
|
||||||
VkStructureType sType;
|
VkStructureType sType;
|
||||||
|
|
@ -153,22 +160,14 @@ typedef struct VkPastPresentationTimingInfoEXT
|
||||||
VkSwapchainKHR swapchain;
|
VkSwapchainKHR swapchain;
|
||||||
} VkPastPresentationTimingInfoEXT;
|
} VkPastPresentationTimingInfoEXT;
|
||||||
|
|
||||||
typedef union VkPresentTimeEXT
|
|
||||||
{
|
|
||||||
uint64_t targetPresentTime;
|
|
||||||
uint64_t presentDuration;
|
|
||||||
} VkPresentTimeEXT;
|
|
||||||
|
|
||||||
typedef struct VkPresentTimingInfoEXT
|
typedef struct VkPresentTimingInfoEXT
|
||||||
{
|
{
|
||||||
VkStructureType sType;
|
VkStructureType sType;
|
||||||
const void *pNext;
|
const void *pNext;
|
||||||
VkPresentTimeEXT time;
|
VkPresentTimingInfoFlagsEXT flags;
|
||||||
|
uint64_t targetTime;
|
||||||
uint64_t timeDomainId;
|
uint64_t timeDomainId;
|
||||||
VkPresentStageFlagsEXT presentStageQueries;
|
VkPresentStageFlagsEXT presentStageQueries;
|
||||||
VkPresentStageFlagsEXT targetPresentStage;
|
|
||||||
VkBool32 presentAtRelativeTime;
|
|
||||||
VkBool32 presentAtNearestRefreshCycle;
|
|
||||||
} VkPresentTimingInfoEXT;
|
} VkPresentTimingInfoEXT;
|
||||||
|
|
||||||
typedef struct VkPresentTimingsInfoEXT
|
typedef struct VkPresentTimingsInfoEXT
|
||||||
|
|
@ -180,12 +179,12 @@ typedef struct VkPresentTimingsInfoEXT
|
||||||
} VkPresentTimingsInfoEXT;
|
} VkPresentTimingsInfoEXT;
|
||||||
|
|
||||||
typedef VkResult(VKAPI_PTR *PFN_vkGetSwapchainTimeDomainPropertiesEXT)(
|
typedef VkResult(VKAPI_PTR *PFN_vkGetSwapchainTimeDomainPropertiesEXT)(
|
||||||
VkDevice device, VkSwapchainKHR swapchain, uint64_t *pTimeDomainsCounter,
|
VkDevice device, VkSwapchainKHR swapchain, VkSwapchainTimeDomainPropertiesEXT *pSwapchainTimeDomainProperties,
|
||||||
VkSwapchainTimeDomainPropertiesEXT *pSwapchainTimeDomainProperties);
|
uint64_t *pTimeDomainsCounter);
|
||||||
|
|
||||||
typedef VkResult(VKAPI_PTR *PFN_vkGetSwapchainTimingPropertiesEXT)(
|
typedef VkResult(VKAPI_PTR *PFN_vkGetSwapchainTimingPropertiesEXT)(
|
||||||
VkDevice device, VkSwapchainKHR swapchain, uint64_t *pSwapchainTimingPropertiesCounter,
|
VkDevice device, VkSwapchainKHR swapchain, VkSwapchainTimingPropertiesEXT *pSwapchainTimingProperties,
|
||||||
VkSwapchainTimingPropertiesEXT *pSwapchainTimingProperties);
|
uint64_t *pSwapchainTimingPropertiesCounter);
|
||||||
|
|
||||||
typedef VkResult(VKAPI_PTR *PFN_vkSetSwapchainPresentTimingQueueSizeEXT)(VkDevice device, VkSwapchainKHR swapchain,
|
typedef VkResult(VKAPI_PTR *PFN_vkSetSwapchainPresentTimingQueueSizeEXT)(VkDevice device, VkSwapchainKHR swapchain,
|
||||||
uint32_t size);
|
uint32_t size);
|
||||||
|
|
@ -200,12 +199,12 @@ wsi_layer_vkSetSwapchainPresentTimingQueueSizeEXT(VkDevice device, VkSwapchainKH
|
||||||
|
|
||||||
VWL_VKAPI_CALL(VkResult)
|
VWL_VKAPI_CALL(VkResult)
|
||||||
wsi_layer_vkGetSwapchainTimingPropertiesEXT(VkDevice device, VkSwapchainKHR swapchain,
|
wsi_layer_vkGetSwapchainTimingPropertiesEXT(VkDevice device, VkSwapchainKHR swapchain,
|
||||||
uint64_t *pSwapchainTimingPropertiesCounter,
|
VkSwapchainTimingPropertiesEXT *pSwapchainTimingProperties,
|
||||||
VkSwapchainTimingPropertiesEXT *pSwapchainTimingProperties) VWL_API_POST;
|
uint64_t *pSwapchainTimingPropertiesCounter) VWL_API_POST;
|
||||||
VWL_VKAPI_CALL(VkResult)
|
VWL_VKAPI_CALL(VkResult)
|
||||||
wsi_layer_vkGetSwapchainTimeDomainPropertiesEXT(
|
wsi_layer_vkGetSwapchainTimeDomainPropertiesEXT(VkDevice device, VkSwapchainKHR swapchain,
|
||||||
VkDevice device, VkSwapchainKHR swapchain, uint64_t *pTimeDomainsCounter,
|
VkSwapchainTimeDomainPropertiesEXT *pSwapchainTimeDomainProperties,
|
||||||
VkSwapchainTimeDomainPropertiesEXT *pSwapchainTimeDomainProperties) VWL_API_POST;
|
uint64_t *pTimeDomainsCounter) VWL_API_POST;
|
||||||
|
|
||||||
VWL_VKAPI_CALL(VkResult)
|
VWL_VKAPI_CALL(VkResult)
|
||||||
wsi_layer_vkGetPastPresentationTimingEXT(
|
wsi_layer_vkGetPastPresentationTimingEXT(
|
||||||
|
|
|
||||||
|
|
@ -576,7 +576,6 @@ VkResult surface_properties::get_present_timing_surface_caps(
|
||||||
present_timing_surface_caps->presentAtAbsoluteTimeSupported = VK_FALSE;
|
present_timing_surface_caps->presentAtAbsoluteTimeSupported = VK_FALSE;
|
||||||
present_timing_surface_caps->presentAtRelativeTimeSupported = VK_FALSE;
|
present_timing_surface_caps->presentAtRelativeTimeSupported = VK_FALSE;
|
||||||
present_timing_surface_caps->presentStageQueries = 0;
|
present_timing_surface_caps->presentStageQueries = 0;
|
||||||
present_timing_surface_caps->presentStageTargets = 0;
|
|
||||||
|
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,13 +39,13 @@
|
||||||
namespace wsi
|
namespace wsi
|
||||||
{
|
{
|
||||||
/* VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT,
|
/* VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT,
|
||||||
* VK_PRESENT_STAGE_IMAGE_LATCHED_BIT_EXT,
|
* VK_PRESENT_STAGE_REQUEST_DEQUEUED_BIT_EXT,
|
||||||
* VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT,
|
* VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT,
|
||||||
* VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_BIT_EXT
|
* VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_BIT_EXT
|
||||||
*/
|
*/
|
||||||
static constexpr size_t MAX_PRESENT_STAGES = 4;
|
static constexpr size_t MAX_PRESENT_STAGES = 4;
|
||||||
const std::array<VkPresentStageFlagBitsEXT, MAX_PRESENT_STAGES> g_present_stages = {
|
const std::array<VkPresentStageFlagBitsEXT, MAX_PRESENT_STAGES> g_present_stages = {
|
||||||
VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT, VK_PRESENT_STAGE_IMAGE_LATCHED_BIT_EXT,
|
VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT, VK_PRESENT_STAGE_REQUEST_DEQUEUED_BIT_EXT,
|
||||||
VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT, VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_BIT_EXT
|
VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT, VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_BIT_EXT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -276,6 +276,7 @@ VkResult wsi_ext_present_timing::queue_submit_queue_end_timing(const layer::devi
|
||||||
}
|
}
|
||||||
|
|
||||||
VkResult wsi_ext_present_timing::add_presentation_query_entry(VkQueue queue, uint64_t present_id, uint32_t image_index,
|
VkResult wsi_ext_present_timing::add_presentation_query_entry(VkQueue queue, uint64_t present_id, uint32_t image_index,
|
||||||
|
uint64_t target_time,
|
||||||
VkPresentStageFlagsEXT present_stage_queries)
|
VkPresentStageFlagsEXT present_stage_queries)
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> lock(m_queue_mutex);
|
const std::lock_guard<std::mutex> lock(m_queue_mutex);
|
||||||
|
|
@ -287,7 +288,7 @@ VkResult wsi_ext_present_timing::add_presentation_query_entry(VkQueue queue, uin
|
||||||
return VK_ERROR_PRESENT_TIMING_QUEUE_FULL_EXT;
|
return VK_ERROR_PRESENT_TIMING_QUEUE_FULL_EXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
wsi::swapchain_presentation_entry presentation_entry(present_stage_queries, present_id, image_index);
|
wsi::swapchain_presentation_entry presentation_entry(target_time, present_stage_queries, present_id, image_index);
|
||||||
if (!m_queue.try_push_back(std::move(presentation_entry)))
|
if (!m_queue.try_push_back(std::move(presentation_entry)))
|
||||||
{
|
{
|
||||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||||
|
|
@ -303,7 +304,7 @@ VkResult wsi_ext_present_timing::add_presentation_query_entry(VkQueue queue, uin
|
||||||
void wsi_ext_present_timing::add_presentation_target_entry(uint32_t image_index,
|
void wsi_ext_present_timing::add_presentation_target_entry(uint32_t image_index,
|
||||||
const VkPresentTimingInfoEXT &timing_info)
|
const VkPresentTimingInfoEXT &timing_info)
|
||||||
{
|
{
|
||||||
assert(timing_info.targetPresentStage);
|
assert(timing_info.targetTime != 0);
|
||||||
m_scheduled_present_targets[image_index] = scheduled_present_target(timing_info);
|
m_scheduled_present_targets[image_index] = scheduled_present_target(timing_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -322,9 +323,10 @@ VkResult wsi_ext_present_timing::add_presentation_entry(VkQueue queue, uint64_t
|
||||||
{
|
{
|
||||||
if (timing_info.presentStageQueries)
|
if (timing_info.presentStageQueries)
|
||||||
{
|
{
|
||||||
TRY_LOG_CALL(add_presentation_query_entry(queue, present_id, image_index, timing_info.presentStageQueries));
|
TRY_LOG_CALL(add_presentation_query_entry(queue, present_id, image_index, timing_info.targetTime,
|
||||||
|
timing_info.presentStageQueries));
|
||||||
}
|
}
|
||||||
if (timing_info.targetPresentStage)
|
if (timing_info.targetTime != 0)
|
||||||
{
|
{
|
||||||
add_presentation_target_entry(image_index, timing_info);
|
add_presentation_target_entry(image_index, timing_info);
|
||||||
}
|
}
|
||||||
|
|
@ -462,9 +464,11 @@ bool wsi_ext_present_timing::is_stage_pending_for_image_index(uint32_t image_ind
|
||||||
return (get_pending_stage_timing(image_index, present_stage) != nullptr);
|
return (get_pending_stage_timing(image_index, present_stage) != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
swapchain_presentation_entry::swapchain_presentation_entry(VkPresentStageFlagsEXT present_stage_queries,
|
swapchain_presentation_entry::swapchain_presentation_entry(uint64_t target_time,
|
||||||
|
VkPresentStageFlagsEXT present_stage_queries,
|
||||||
uint64_t present_id, uint32_t image_index)
|
uint64_t present_id, uint32_t image_index)
|
||||||
: m_target_stages(0)
|
: m_target_time(target_time)
|
||||||
|
, m_target_stages(0)
|
||||||
, m_present_id(present_id)
|
, m_present_id(present_id)
|
||||||
, m_image_index(image_index)
|
, m_image_index(image_index)
|
||||||
, m_num_present_stages(0)
|
, m_num_present_stages(0)
|
||||||
|
|
@ -474,7 +478,7 @@ swapchain_presentation_entry::swapchain_presentation_entry(VkPresentStageFlagsEX
|
||||||
m_queue_end_timing = swapchain_presentation_timing();
|
m_queue_end_timing = swapchain_presentation_timing();
|
||||||
m_num_present_stages++;
|
m_num_present_stages++;
|
||||||
}
|
}
|
||||||
if (present_stage_queries & VK_PRESENT_STAGE_IMAGE_LATCHED_BIT_EXT)
|
if (present_stage_queries & VK_PRESENT_STAGE_REQUEST_DEQUEUED_BIT_EXT)
|
||||||
{
|
{
|
||||||
m_latch_timing = swapchain_presentation_timing();
|
m_latch_timing = swapchain_presentation_timing();
|
||||||
m_num_present_stages++;
|
m_num_present_stages++;
|
||||||
|
|
@ -510,7 +514,7 @@ bool swapchain_presentation_entry::is_pending(VkPresentStageFlagBitsEXT stage)
|
||||||
bool swapchain_presentation_entry::has_outstanding_stages()
|
bool swapchain_presentation_entry::has_outstanding_stages()
|
||||||
{
|
{
|
||||||
return (is_pending(VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT) ||
|
return (is_pending(VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT) ||
|
||||||
is_pending(VK_PRESENT_STAGE_IMAGE_LATCHED_BIT_EXT) ||
|
is_pending(VK_PRESENT_STAGE_REQUEST_DEQUEUED_BIT_EXT) ||
|
||||||
is_pending(VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT) ||
|
is_pending(VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT) ||
|
||||||
is_pending(VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_BIT_EXT));
|
is_pending(VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_BIT_EXT));
|
||||||
}
|
}
|
||||||
|
|
@ -544,7 +548,7 @@ std::optional<std::reference_wrapper<swapchain_presentation_timing>> swapchain_p
|
||||||
return *m_queue_end_timing;
|
return *m_queue_end_timing;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case VK_PRESENT_STAGE_IMAGE_LATCHED_BIT_EXT:
|
case VK_PRESENT_STAGE_REQUEST_DEQUEUED_BIT_EXT:
|
||||||
if (m_latch_timing.has_value())
|
if (m_latch_timing.has_value())
|
||||||
{
|
{
|
||||||
return *m_latch_timing;
|
return *m_latch_timing;
|
||||||
|
|
@ -602,6 +606,7 @@ void swapchain_presentation_entry::populate(VkPastPresentationTimingEXT &timing)
|
||||||
{
|
{
|
||||||
timing.presentId = m_present_id;
|
timing.presentId = m_present_id;
|
||||||
timing.reportComplete = !has_outstanding_stages();
|
timing.reportComplete = !has_outstanding_stages();
|
||||||
|
timing.targetTime = m_target_time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,11 @@ struct swapchain_presentation_timing
|
||||||
*/
|
*/
|
||||||
struct swapchain_presentation_entry
|
struct swapchain_presentation_entry
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Target time used in the present request.
|
||||||
|
*/
|
||||||
|
uint64_t m_target_time{ 0 };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The target stages for the presentation entry.
|
* The target stages for the presentation entry.
|
||||||
*/
|
*/
|
||||||
|
|
@ -127,7 +132,7 @@ struct swapchain_presentation_entry
|
||||||
std::optional<swapchain_presentation_timing> m_first_pixel_out_timing;
|
std::optional<swapchain_presentation_timing> m_first_pixel_out_timing;
|
||||||
std::optional<swapchain_presentation_timing> m_first_pixel_visible_timing;
|
std::optional<swapchain_presentation_timing> m_first_pixel_visible_timing;
|
||||||
|
|
||||||
swapchain_presentation_entry(VkPresentStageFlagsEXT present_stage_queries, uint64_t present_id,
|
swapchain_presentation_entry(uint64_t target_time, VkPresentStageFlagsEXT present_stage_queries, uint64_t present_id,
|
||||||
uint32_t image_index);
|
uint32_t image_index);
|
||||||
swapchain_presentation_entry(swapchain_presentation_entry &&) noexcept = default;
|
swapchain_presentation_entry(swapchain_presentation_entry &&) noexcept = default;
|
||||||
swapchain_presentation_entry &operator=(swapchain_presentation_entry &&) noexcept = default;
|
swapchain_presentation_entry &operator=(swapchain_presentation_entry &&) noexcept = default;
|
||||||
|
|
@ -292,19 +297,15 @@ private:
|
||||||
struct scheduled_present_target
|
struct scheduled_present_target
|
||||||
{
|
{
|
||||||
scheduled_present_target(const VkPresentTimingInfoEXT &timing_info)
|
scheduled_present_target(const VkPresentTimingInfoEXT &timing_info)
|
||||||
: m_target_stage(timing_info.targetPresentStage)
|
: m_time_domain_id(timing_info.timeDomainId)
|
||||||
, m_time_domain_id(timing_info.timeDomainId)
|
, m_flags(timing_info.flags)
|
||||||
, m_present_at_nearest_refresh_cycle(timing_info.presentAtNearestRefreshCycle)
|
, m_target_present_time(timing_info.targetTime)
|
||||||
, m_present_at_relative_time(timing_info.presentAtRelativeTime)
|
|
||||||
, m_target_present_time(timing_info.time)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
VkPresentStageFlagsEXT m_target_stage;
|
|
||||||
uint64_t m_time_domain_id;
|
uint64_t m_time_domain_id;
|
||||||
bool m_present_at_nearest_refresh_cycle;
|
VkPresentTimingInfoFlagsEXT m_flags;
|
||||||
bool m_present_at_relative_time;
|
uint64_t m_target_present_time;
|
||||||
VkPresentTimeEXT m_target_present_time;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -378,12 +379,13 @@ public:
|
||||||
* @param queue The Vulkan queue used to submit synchronization commands.
|
* @param queue The Vulkan queue used to submit synchronization commands.
|
||||||
* @param present_id The present id of the current presentation.
|
* @param present_id The present id of the current presentation.
|
||||||
* @param image_index The index of the image in the swapchain.
|
* @param image_index The index of the image in the swapchain.
|
||||||
|
* @param target_time The target time for the presentation.
|
||||||
* @param present_stage_queries The present stages application had requested timings for.
|
* @param present_stage_queries The present stages application had requested timings for.
|
||||||
*
|
*
|
||||||
* @return VK_SUCCESS when the entry was inserted successfully and VK_ERROR_OUT_OF_HOST_MEMORY
|
* @return VK_SUCCESS when the entry was inserted successfully and VK_ERROR_OUT_OF_HOST_MEMORY
|
||||||
* when there is no host memory.
|
* when there is no host memory.
|
||||||
*/
|
*/
|
||||||
VkResult add_presentation_query_entry(VkQueue queue, uint64_t present_id, uint32_t image_index,
|
VkResult add_presentation_query_entry(VkQueue queue, uint64_t present_id, uint32_t image_index, uint64_t target_time,
|
||||||
VkPresentStageFlagsEXT present_stage_queries);
|
VkPresentStageFlagsEXT present_stage_queries);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -82,8 +82,8 @@ util::unique_ptr<wsi_ext_present_timing_headless> wsi_ext_present_timing_headles
|
||||||
|
|
||||||
if (monotonic_domain)
|
if (monotonic_domain)
|
||||||
{
|
{
|
||||||
if (!domains.try_push_back(
|
if (!domains.try_push_back(allocator.make_unique<wsi::vulkan_time_domain>(
|
||||||
allocator.make_unique<wsi::vulkan_time_domain>(VK_PRESENT_STAGE_IMAGE_LATCHED_BIT_EXT, *monotonic_domain)))
|
VK_PRESENT_STAGE_REQUEST_DEQUEUED_BIT_EXT, *monotonic_domain)))
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
@ -116,7 +116,7 @@ VkResult wsi_ext_present_timing_headless::get_swapchain_timing_properties(
|
||||||
|
|
||||||
timing_properties_counter = 1;
|
timing_properties_counter = 1;
|
||||||
timing_properties.refreshDuration = fixed_refresh_duration_ns;
|
timing_properties.refreshDuration = fixed_refresh_duration_ns;
|
||||||
timing_properties.variableRefreshDelay = UINT64_MAX;
|
timing_properties.refreshInterval = fixed_refresh_duration_ns;
|
||||||
|
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -261,14 +261,13 @@ VkResult surface_properties::get_present_timing_surface_caps(
|
||||||
[](auto &domain) { return std::get<1>(domain); });
|
[](auto &domain) { return std::get<1>(domain); });
|
||||||
if (it_monotonic_supported != monotonic_domains.end())
|
if (it_monotonic_supported != monotonic_domains.end())
|
||||||
{
|
{
|
||||||
monotonic_present_stages_supported |= VK_PRESENT_STAGE_IMAGE_LATCHED_BIT_EXT |
|
monotonic_present_stages_supported |= VK_PRESENT_STAGE_REQUEST_DEQUEUED_BIT_EXT |
|
||||||
VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT |
|
VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT |
|
||||||
VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_BIT_EXT;
|
VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_BIT_EXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
present_timing_surface_caps->presentStageQueries =
|
present_timing_surface_caps->presentStageQueries =
|
||||||
VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT | monotonic_present_stages_supported;
|
VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT | monotonic_present_stages_supported;
|
||||||
present_timing_surface_caps->presentStageTargets = monotonic_present_stages_supported;
|
|
||||||
|
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -225,28 +225,22 @@ void swapchain::present_image(const pending_present_request &pending_present)
|
||||||
auto presentation_target = ext_present_timing->get_presentation_target_entry(pending_present.image_index);
|
auto presentation_target = ext_present_timing->get_presentation_target_entry(pending_present.image_index);
|
||||||
if (presentation_target)
|
if (presentation_target)
|
||||||
{
|
{
|
||||||
const VkPresentStageFlagsEXT supported_target_stages = VK_PRESENT_STAGE_IMAGE_LATCHED_BIT_EXT |
|
/* No support for relative presentation mode currently */
|
||||||
VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT |
|
assert(!(presentation_target->m_flags & VK_PRESENT_TIMING_INFO_PRESENT_AT_RELATIVE_TIME_BIT_EXT));
|
||||||
VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_BIT_EXT;
|
if (!(presentation_target->m_flags & VK_PRESENT_TIMING_INFO_PRESENT_AT_RELATIVE_TIME_BIT_EXT))
|
||||||
if ((presentation_target->m_target_stage & supported_target_stages) != 0)
|
|
||||||
{
|
{
|
||||||
/* No support for relative presentation mode currently */
|
/* No need to check whether we need to present at nearest refresh cycle since this backend is not
|
||||||
assert(!presentation_target->m_present_at_relative_time);
|
limited by the refresh cycles. */
|
||||||
if (!presentation_target->m_present_at_relative_time)
|
uint64_t absolute_future_present_time_ns = presentation_target->m_target_present_time;
|
||||||
|
auto current_time_ns = ext_present_timing->get_current_clock_time_ns();
|
||||||
|
if (*current_time_ns < absolute_future_present_time_ns)
|
||||||
{
|
{
|
||||||
/* No need to check whether we need to present at nearest refresh cycle since this backend is not
|
/* Sleep until we can schedule the image for completion.
|
||||||
limited by the refresh cycles. */
|
* This is OK as the sleep should only be dispatched on the page_flip thread and not on main. */
|
||||||
uint64_t absolute_future_present_time_ns = presentation_target->m_target_present_time.targetPresentTime;
|
assert(m_page_flip_thread_run);
|
||||||
auto current_time_ns = ext_present_timing->get_current_clock_time_ns();
|
|
||||||
if (*current_time_ns < absolute_future_present_time_ns)
|
|
||||||
{
|
|
||||||
/* Sleep until we can schedule the image for completion.
|
|
||||||
* This is OK as the sleep should only be dispatched on the page_flip thread and not on main. */
|
|
||||||
assert(m_page_flip_thread_run);
|
|
||||||
|
|
||||||
int64_t time_diff = absolute_future_present_time_ns - *current_time_ns;
|
int64_t time_diff = absolute_future_present_time_ns - *current_time_ns;
|
||||||
std::this_thread::sleep_for(std::chrono::nanoseconds(time_diff));
|
std::this_thread::sleep_for(std::chrono::nanoseconds(time_diff));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -272,7 +266,7 @@ void swapchain::present_image(const pending_present_request &pending_present)
|
||||||
}
|
}
|
||||||
|
|
||||||
VkPresentStageFlagBitsEXT stages[] = {
|
VkPresentStageFlagBitsEXT stages[] = {
|
||||||
VK_PRESENT_STAGE_IMAGE_LATCHED_BIT_EXT,
|
VK_PRESENT_STAGE_REQUEST_DEQUEUED_BIT_EXT,
|
||||||
VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT,
|
VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT,
|
||||||
VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_BIT_EXT,
|
VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_BIT_EXT,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ VkResult wsi_ext_present_timing_wayland::get_swapchain_timing_properties(
|
||||||
{
|
{
|
||||||
timing_properties_counter = 0;
|
timing_properties_counter = 0;
|
||||||
timing_properties.refreshDuration = 0;
|
timing_properties.refreshDuration = 0;
|
||||||
timing_properties.variableRefreshDelay = 0;
|
timing_properties.refreshInterval = 0;
|
||||||
|
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -467,10 +467,10 @@ VkResult surface_properties::get_present_timing_surface_caps(
|
||||||
|
|
||||||
/* The extension supports scheduling targets only on FIFO & FIFO_RELAXED modes. We currently only have
|
/* The extension supports scheduling targets only on FIFO & FIFO_RELAXED modes. We currently only have
|
||||||
support for scheduling presents when using the presentation thread. While FIFO runs on Wayland in
|
support for scheduling presents when using the presentation thread. While FIFO runs on Wayland in
|
||||||
threaded mode, FIFO_RELAXED does not. If you are adding any supported stage to presentStageTargets,
|
threaded mode, FIFO_RELAXED does not. If you are setting presentAtAbsoluteTimeSupported or
|
||||||
make sure to check that swapchain cannot be created with present timing support on present modes that
|
presentAtRelativeTimeSupported to VK_TRUE, make sure to check that swapchain cannot be created
|
||||||
|
with present timing support on present modes that
|
||||||
do not use presentation thread unless support has been added in other ways. */
|
do not use presentation thread unless support has been added in other ways. */
|
||||||
present_timing_surface_caps->presentStageTargets = 0;
|
|
||||||
|
|
||||||
if (specific_surface->get_presentation_time_interface() != nullptr)
|
if (specific_surface->get_presentation_time_interface() != nullptr)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ swapchain::~swapchain()
|
||||||
|
|
||||||
if (m_buffer_queue != nullptr)
|
if (m_buffer_queue != nullptr)
|
||||||
{
|
{
|
||||||
|
wl_display_roundtrip_queue(m_display, m_buffer_queue);
|
||||||
wl_event_queue_destroy(m_buffer_queue);
|
wl_event_queue_destroy(m_buffer_queue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue