mirror of
https://gitlab.freedesktop.org/mesa/vulkan-wsi-layer.git
synced 2025-12-27 04:30:09 +01:00
Merge 'Handle VkPresentTimingsInfoEXT' into 'main'
See merge request mesa/vulkan-wsi-layer!116
This commit is contained in:
commit
e8cacef0de
5 changed files with 153 additions and 3 deletions
|
|
@ -29,6 +29,7 @@
|
|||
*/
|
||||
#include <cassert>
|
||||
#include "wsi_layer_experimental.hpp"
|
||||
#include "wsi/swapchain_base.hpp"
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
|
||||
|
|
@ -38,8 +39,9 @@
|
|||
VWL_VKAPI_CALL(VkResult)
|
||||
wsi_layer_vkSetSwapchainPresentTimingQueueSizeEXT(VkDevice device, VkSwapchainKHR swapchain, uint32_t size) VWL_API_POST
|
||||
{
|
||||
VkResult result = VK_SUCCESS;
|
||||
return result;
|
||||
assert(swapchain != VK_NULL_HANDLE);
|
||||
auto *sc = reinterpret_cast<wsi::swapchain_base *>(swapchain);
|
||||
return sc->presentation_timing_queue_set_size(size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -187,10 +187,17 @@ wsi_layer_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo)
|
|||
VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_FENCE_INFO_EXT, present_info->pNext);
|
||||
const auto swapchain_present_mode_info = util::find_extension<VkSwapchainPresentModeInfoEXT>(
|
||||
VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_MODE_INFO_EXT, present_info->pNext);
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
const auto present_timings_info =
|
||||
util::find_extension<VkPresentTimingsInfoEXT>(VK_STRUCTURE_TYPE_PRESENT_TIMINGS_INFO_EXT, present_info->pNext);
|
||||
if (present_timings_info)
|
||||
{
|
||||
assert(present_timings_info->swapchainCount == pPresentInfo->swapchainCount);
|
||||
}
|
||||
#endif
|
||||
for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i)
|
||||
{
|
||||
VkSwapchainKHR swapc = pPresentInfo->pSwapchains[i];
|
||||
|
||||
auto *sc = reinterpret_cast<wsi::swapchain_base *>(swapc);
|
||||
assert(sc != nullptr);
|
||||
|
||||
|
|
@ -213,6 +220,13 @@ wsi_layer_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo)
|
|||
|
||||
present_params.use_image_present_semaphore = use_image_present_semaphore;
|
||||
present_params.handle_present_frame_boundary_event = frame_boundary_event_handled;
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
if (present_timings_info)
|
||||
{
|
||||
present_params.present_timing_info = &(present_timings_info->pTimingInfos[i]);
|
||||
}
|
||||
#endif
|
||||
VkResult res = sc->queue_present(queue, present_info, present_params);
|
||||
if (pPresentInfo->pResults != nullptr)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -368,6 +368,30 @@ public:
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Like std::vector::reserve but doesn't throw on out of memory errors.
|
||||
*
|
||||
* @param size The new capacity of the container. Same as std::vector::reserve.
|
||||
* @return true If the container was resized successfuly.
|
||||
* @return false If the host has run out of memory or when there is a length error.
|
||||
*/
|
||||
bool try_reserve(size_t size) noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
base::reserve(size);
|
||||
return true;
|
||||
}
|
||||
catch (std::bad_alloc &e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
catch (const std::length_error &e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace util */
|
||||
|
|
|
|||
|
|
@ -224,6 +224,9 @@ swapchain_base::swapchain_base(layer::device_private_data &dev_data, const VkAll
|
|||
, m_error_state(VK_NOT_READY)
|
||||
, m_started_presenting(false)
|
||||
, m_frame_boundary_handler(m_device_data)
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
, m_presentation_timing(m_allocator)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -669,6 +672,22 @@ VkResult swapchain_base::notify_presentation_engine(const pending_present_reques
|
|||
VkResult swapchain_base::queue_present(VkQueue queue, const VkPresentInfoKHR *present_info,
|
||||
const swapchain_presentation_parameters &submit_info)
|
||||
{
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
if (submit_info.present_timing_info)
|
||||
{
|
||||
wsi::swapchain_presentation_entry presentation_entry = {};
|
||||
presentation_entry.present_id = submit_info.pending_present.present_id;
|
||||
if ((m_presentation_timing.size()) >= m_presentation_timing.capacity())
|
||||
{
|
||||
return VK_ERROR_PRESENT_TIMING_QUEUE_FULL_EXT;
|
||||
}
|
||||
|
||||
if (!m_presentation_timing.try_push_back(presentation_entry))
|
||||
{
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (submit_info.switch_presentation_mode)
|
||||
{
|
||||
|
|
@ -844,4 +863,48 @@ void swapchain_base::set_present_id(uint64_t value)
|
|||
}
|
||||
}
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
VkResult swapchain_base::presentation_timing_queue_set_size(size_t queue_size)
|
||||
{
|
||||
if (presentation_timing_get_num_outstanding_results() > queue_size)
|
||||
{
|
||||
return VK_NOT_READY;
|
||||
}
|
||||
|
||||
util::vector<swapchain_presentation_entry> presentation_timing(
|
||||
util::allocator(m_allocator, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE));
|
||||
if (!presentation_timing.try_reserve(queue_size))
|
||||
{
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
for (auto iter : m_presentation_timing)
|
||||
{
|
||||
if (iter.is_outstanding)
|
||||
{
|
||||
if (!presentation_timing.try_push_back(iter))
|
||||
{
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_presentation_timing.swap(presentation_timing);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
size_t swapchain_base::presentation_timing_get_num_outstanding_results()
|
||||
{
|
||||
size_t num_outstanding = 0;
|
||||
|
||||
for (const auto &iter : m_presentation_timing)
|
||||
{
|
||||
if (iter.is_outstanding)
|
||||
{
|
||||
num_outstanding++;
|
||||
}
|
||||
}
|
||||
return num_outstanding;
|
||||
}
|
||||
#endif
|
||||
|
||||
} /* namespace wsi */
|
||||
|
|
|
|||
|
|
@ -110,8 +110,29 @@ struct swapchain_presentation_parameters
|
|||
* to underlying layers/ICD if the feature is enabled.
|
||||
*/
|
||||
VkBool32 handle_present_frame_boundary_event{ true };
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
/**
|
||||
* Pointer to the present timing info.
|
||||
*/
|
||||
const VkPresentTimingInfoEXT *present_timing_info{ nullptr };
|
||||
#endif
|
||||
};
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
struct swapchain_presentation_entry
|
||||
{
|
||||
/**
|
||||
* Whether this entry is an outstanding result or not.
|
||||
*/
|
||||
bool is_outstanding{ false };
|
||||
/**
|
||||
* The present id.
|
||||
*/
|
||||
uint64_t present_id{ 0 };
|
||||
};
|
||||
#endif
|
||||
|
||||
#if WSI_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN
|
||||
struct image_compression_control_params
|
||||
{
|
||||
|
|
@ -274,6 +295,18 @@ public:
|
|||
*/
|
||||
VkResult is_bind_allowed(uint32_t image_index) const;
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
/**
|
||||
* @brief Set the size for the presentation timing queue
|
||||
*
|
||||
* @param queue_size The new queue size to set.
|
||||
*
|
||||
* @return VK_SUCCESS on success, VK_ERROR_OUT_OF_HOST_MEMORY when there is not enough memory, VK_NOT_READY otherwise.
|
||||
* .
|
||||
*/
|
||||
VkResult presentation_timing_queue_set_size(size_t queue_size);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
layer::device_private_data &m_device_data;
|
||||
|
||||
|
|
@ -710,6 +743,20 @@ private:
|
|||
*
|
||||
*/
|
||||
frame_boundary_handler m_frame_boundary_handler;
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
/**
|
||||
* @brief Queue for presentation timings.
|
||||
*/
|
||||
util::vector<swapchain_presentation_entry> m_presentation_timing;
|
||||
|
||||
/**
|
||||
* @brief Get the size of the presentation timing queue
|
||||
*
|
||||
* @return queue size of the presentation timestamp queue.
|
||||
*/
|
||||
size_t presentation_timing_get_num_outstanding_results();
|
||||
#endif
|
||||
};
|
||||
|
||||
} /* namespace wsi */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue