mirror of
https://gitlab.freedesktop.org/mesa/vulkan-wsi-layer.git
synced 2025-12-20 06:50:08 +01:00
Enables the present wait extension by default - experimental flag is no longer needed.
Fixes the following issues: * For Wayland backend, populates the presentation feedback listener with all callbacks as it is considered a fault by the protocol to not implement those * For Wayland backend presentation feedback listener, forwards the feedback_discarded event to present ID as there could be situations where previously submitted buffers are discarded, such as when swapchains are using the MAILBOX presentation mode. * For all swapchains, communicate critical errors back to present wait extension as otherwise, all callers waiting that are waiting on present to be delivered in vkWaitForPresentKHR call will never exit. * Expanded the implementation in vkWaitForPresentKHR to be able to return critical swapchain errors if they have occured during the wait time. * Fix issues in present ID where infinite waits could result in the vkWaitForPresentKHR call returning immediately due to UINT64_MAX timeout resulting in overflowing the system clock used in std::condition_variable Change-Id: I1e475c3073c05394db259657eae1da21764a5a5c Signed-off-by: Normunds Rieksts <normunds.rieksts@arm.com> Signed-off-by: Alex Bates <alex.bates@arm.com>
This commit is contained in:
parent
604b1e6a17
commit
cedf53a2be
19 changed files with 138 additions and 65 deletions
|
|
@ -146,13 +146,13 @@ if(BUILD_WSI_WAYLAND)
|
|||
wsi/wayland/surface.cpp
|
||||
wsi/wayland/wl_helpers.cpp
|
||||
wsi/wayland/swapchain.cpp
|
||||
wsi/wayland/present_wait_wayland.cpp
|
||||
wsi/swapchain_image_create_extensions/external_memory_extension.cpp)
|
||||
|
||||
if(VULKAN_WSI_LAYER_EXPERIMENTAL)
|
||||
target_sources(wayland_wsi PRIVATE wsi/wayland/present_id_wayland.cpp)
|
||||
target_sources(wayland_wsi PRIVATE wsi/wayland/present_timing_handler.cpp)
|
||||
target_sources(wayland_wsi PRIVATE wsi/wayland/wp_presentation_feedback.cpp)
|
||||
target_sources(wayland_wsi PRIVATE wsi/wayland/present_wait_wayland.cpp)
|
||||
endif()
|
||||
|
||||
pkg_check_modules(WAYLAND_CLIENT REQUIRED wayland-client)
|
||||
|
|
@ -229,11 +229,11 @@ if(BUILD_WSI_HEADLESS)
|
|||
add_library(wsi_headless STATIC
|
||||
wsi/headless/surface_properties.cpp
|
||||
wsi/headless/surface.cpp
|
||||
wsi/headless/swapchain.cpp)
|
||||
wsi/headless/swapchain.cpp
|
||||
wsi/headless/present_wait_headless.cpp)
|
||||
|
||||
if(VULKAN_WSI_LAYER_EXPERIMENTAL)
|
||||
target_sources(wsi_headless PRIVATE wsi/headless/present_timing_handler.cpp)
|
||||
target_sources(wsi_headless PRIVATE wsi/headless/present_wait_headless.cpp)
|
||||
endif()
|
||||
|
||||
target_include_directories(wsi_headless PRIVATE
|
||||
|
|
@ -255,11 +255,8 @@ if (BUILD_WSI_DISPLAY)
|
|||
wsi/display/surface_properties.cpp
|
||||
wsi/display/swapchain.cpp
|
||||
wsi/display/surface.cpp
|
||||
wsi/swapchain_image_create_extensions/external_memory_extension.cpp)
|
||||
|
||||
if(VULKAN_WSI_LAYER_EXPERIMENTAL)
|
||||
target_sources(wsi_display PRIVATE wsi/display/present_wait_display.cpp)
|
||||
endif()
|
||||
wsi/swapchain_image_create_extensions/external_memory_extension.cpp
|
||||
wsi/display/present_wait_display.cpp)
|
||||
|
||||
pkg_check_modules(LIBDRM REQUIRED libdrm)
|
||||
message(STATUS "Using libdrm include directories: ${LIBDRM_INCLUDE_DIRS}")
|
||||
|
|
@ -295,6 +292,7 @@ add_library(${PROJECT_NAME} SHARED
|
|||
layer/surface_api.cpp
|
||||
layer/swapchain_api.cpp
|
||||
layer/swapchain_maintenance_api.cpp
|
||||
layer/present_wait_api.cpp
|
||||
util/timed_semaphore.cpp
|
||||
util/custom_allocator.cpp
|
||||
util/extension_list.cpp
|
||||
|
|
@ -303,6 +301,7 @@ add_library(${PROJECT_NAME} SHARED
|
|||
wsi/external_memory.cpp
|
||||
wsi/extensions/image_compression_control.cpp
|
||||
wsi/extensions/present_id.cpp
|
||||
wsi/extensions/present_wait.cpp
|
||||
wsi/extensions/frame_boundary.cpp
|
||||
wsi/extensions/wsi_extension.cpp
|
||||
wsi/extensions/swapchain_maintenance.cpp
|
||||
|
|
@ -315,11 +314,9 @@ add_library(${PROJECT_NAME} SHARED
|
|||
if (VULKAN_WSI_LAYER_EXPERIMENTAL)
|
||||
target_sources(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/layer/present_timing_api.cpp)
|
||||
target_sources(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/wsi/extensions/present_timing.cpp)
|
||||
target_sources(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/layer/present_wait_api.cpp)
|
||||
target_sources(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/wsi/extensions/present_wait.cpp)
|
||||
add_definitions("-DVULKAN_WSI_LAYER_EXPERIMENTAL=1")
|
||||
else()
|
||||
list(APPEND JSON_COMMANDS COMMAND sed -Ei '/VK_EXT_present_timing|VK_KHR_present_wait|VK_EXT_present_mode_fifo_latest_ready/d' ${CMAKE_CURRENT_BINARY_DIR}/VkLayer_window_system_integration.json)
|
||||
list(APPEND JSON_COMMANDS COMMAND sed -Ei '/VK_EXT_present_timing|VK_EXT_present_mode_fifo_latest_ready/d' ${CMAKE_CURRENT_BINARY_DIR}/VkLayer_window_system_integration.json)
|
||||
add_definitions("-DVULKAN_WSI_LAYER_EXPERIMENTAL=0")
|
||||
endif()
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ implements the following extensions:
|
|||
* VK_KHR_shared_presentable_image
|
||||
* VK_EXT_image_compression_control_swapchain
|
||||
* VK_KHR_present_id
|
||||
* VK_KHR_present_wait
|
||||
* VK_EXT_swapchain_maintenance1
|
||||
|
||||
## Building
|
||||
|
|
|
|||
|
|
@ -384,14 +384,12 @@ VKAPI_ATTR VkResult create_device(VkPhysicalDevice physicalDevice, const VkDevic
|
|||
physical_device_swapchain_maintenance1_features->swapchainMaintenance1);
|
||||
}
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
auto *present_wait_features = util::find_extension<VkPhysicalDevicePresentWaitFeaturesKHR>(
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR, pCreateInfo->pNext);
|
||||
if (present_wait_features != nullptr)
|
||||
{
|
||||
device_data.set_present_wait_enabled(present_wait_features->presentWait);
|
||||
}
|
||||
#endif
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
|
@ -492,14 +490,12 @@ wsi_layer_vkGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physical_device,
|
|||
swapchain_maintenance1_features->swapchainMaintenance1 = VK_FALSE;
|
||||
}
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
auto *present_wait_features = util::find_extension<VkPhysicalDevicePresentWaitFeaturesKHR>(
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR, pFeatures->pNext);
|
||||
if (present_wait_features != nullptr)
|
||||
{
|
||||
present_wait_features->presentWait = VK_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
instance.disp.GetPhysicalDeviceFeatures2KHR(physical_device, pFeatures);
|
||||
|
||||
|
|
@ -521,7 +517,6 @@ wsi_layer_vkGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physical_device,
|
|||
|
||||
wsi::set_swapchain_maintenance1_state(physical_device, swapchain_maintenance1_features);
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
if (present_wait_features != nullptr)
|
||||
{
|
||||
/* If there is an surface extension in use that is unsupported by the layer, defer to the ICD */
|
||||
|
|
@ -531,6 +526,7 @@ wsi_layer_vkGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physical_device,
|
|||
}
|
||||
}
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
auto *present_timing_features = util::find_extension<VkPhysicalDevicePresentTimingFeaturesEXT>(
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_TIMING_FEATURES_EXT, pFeatures->pNext);
|
||||
if (present_timing_features != nullptr)
|
||||
|
|
@ -614,12 +610,10 @@ wsi_layer_vkGetDeviceProcAddr(VkDevice device, const char *funcName) VWL_API_POS
|
|||
{
|
||||
GET_PROC_ADDR(vkReleaseSwapchainImagesEXT);
|
||||
}
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
if (layer::device_private_data::get(device).is_device_extension_enabled(VK_KHR_PRESENT_WAIT_EXTENSION_NAME))
|
||||
{
|
||||
GET_PROC_ADDR(vkWaitForPresentKHR);
|
||||
}
|
||||
#endif
|
||||
|
||||
return layer::device_private_data::get(device).disp.get_user_enabled_entrypoint(
|
||||
device, layer::device_private_data::get(device).instance_data.api_version, funcName);
|
||||
|
|
|
|||
|
|
@ -33,8 +33,6 @@
|
|||
|
||||
#include "present_wait_api.hpp"
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
|
||||
/**
|
||||
* @brief Implements vkSetSwapchainPresentTimingQueueSizeEXT Vulkan entrypoint.
|
||||
*/
|
||||
|
|
@ -55,5 +53,3 @@ wsi_layer_vkWaitForPresentKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_
|
|||
|
||||
return ext->wait_for_present_id(present_id, timeout);
|
||||
}
|
||||
|
||||
#endif /* VULKAN_WSI_LAYER_EXPERIMENTAL */
|
||||
|
|
|
|||
|
|
@ -30,10 +30,6 @@
|
|||
#include <vulkan/vulkan.h>
|
||||
#include <util/macros.hpp>
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
|
||||
VWL_VKAPI_CALL(VkResult)
|
||||
wsi_layer_vkWaitForPresentKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t present_id,
|
||||
uint64_t timeout) VWL_API_POST;
|
||||
|
||||
#endif /* VULKAN_WSI_LAYER_EXPERIMENTAL */
|
||||
|
|
|
|||
|
|
@ -634,7 +634,6 @@ bool device_private_data::is_swapchain_maintenance1_enabled() const
|
|||
return swapchain_maintenance1_enabled;
|
||||
}
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
void device_private_data::set_present_wait_enabled(bool enable)
|
||||
{
|
||||
present_wait_enabled = enable;
|
||||
|
|
@ -645,6 +644,7 @@ bool device_private_data::is_present_wait_enabled()
|
|||
return present_wait_enabled;
|
||||
}
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
void device_private_data::set_present_mode_fifo_latest_ready_enabled(bool enable)
|
||||
{
|
||||
present_mode_fifo_latest_ready_enabled = enable;
|
||||
|
|
|
|||
|
|
@ -370,7 +370,6 @@ private:
|
|||
EP(GetSwapchainTimeDomainPropertiesEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) \
|
||||
EP(GetSwapchainTimingPropertiesEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) \
|
||||
EP(SetSwapchainPresentTimingQueueSizeEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) \
|
||||
EP(WaitForPresentKHR, VK_KHR_PRESENT_WAIT_EXTENSION_NAME, API_VERSION_MAX, false, ) \
|
||||
EP(GetPastPresentationTimingEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, )
|
||||
#else
|
||||
#define DEVICE_ENTRYPOINTS_LIST_EXPERIMENTAL(EP)
|
||||
|
|
@ -463,6 +462,8 @@ private:
|
|||
EP(GetCalibratedTimestampsEXT, VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME, API_VERSION_MAX, false, ) \
|
||||
/* VK_KHR_calibrated_timestamps */ \
|
||||
EP(GetCalibratedTimestampsKHR, VK_KHR_CALIBRATED_TIMESTAMPS_EXTENSION_NAME, API_VERSION_MAX, false, ) \
|
||||
/* VK_KHR_present_wait */ \
|
||||
EP(WaitForPresentKHR, VK_KHR_PRESENT_WAIT_EXTENSION_NAME, API_VERSION_MAX, false, ) \
|
||||
/* Custom entrypoints */ \
|
||||
DEVICE_ENTRYPOINTS_LIST_EXPANSION(EP)
|
||||
|
||||
|
|
@ -940,7 +941,6 @@ public:
|
|||
*/
|
||||
bool is_swapchain_maintenance1_enabled() const;
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
/**
|
||||
* @brief Set whether present wait feature is enabled.
|
||||
*
|
||||
|
|
@ -954,7 +954,6 @@ public:
|
|||
* @return true if supported, false otherwise.
|
||||
*/
|
||||
bool is_present_wait_enabled();
|
||||
#endif
|
||||
|
||||
private:
|
||||
/* Allow util::allocator to access the private constructor */
|
||||
|
|
@ -1013,13 +1012,13 @@ private:
|
|||
*/
|
||||
bool swapchain_maintenance1_enabled{ false };
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
/**
|
||||
* @brief Stores whether the device supports the present wait feature.
|
||||
*
|
||||
*/
|
||||
bool present_wait_enabled{ false };
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
/**
|
||||
* @brief Stores whether the device has enabled support for the present timing features.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file present_wait_headless.cpp
|
||||
* @file present_wait_display.cpp
|
||||
*
|
||||
* @brief Contains the base class declaration for the VK_KHR_present_wait extension.
|
||||
*/
|
||||
|
|
@ -42,8 +42,8 @@ wsi_ext_present_wait_display::wsi_ext_present_wait_display(wsi_ext_present_id &p
|
|||
|
||||
VkResult wsi_ext_present_wait_display::wait_for_update(uint64_t present_id, uint64_t timeout_in_ns)
|
||||
{
|
||||
return m_present_id_ext.wait_for_present_id(present_id, timeout_in_ns) ? VK_SUCCESS : VK_TIMEOUT;
|
||||
return m_present_id_ext.wait_for_present_id(present_id, timeout_in_ns);
|
||||
}
|
||||
|
||||
} /* namespace wayland */
|
||||
} /* namespace display */
|
||||
} /* namespace wsi */
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file present_wait_headless.hpp
|
||||
* @file present_wait_display.hpp
|
||||
*
|
||||
* @brief Contains the base class declaration for the VK_KHR_present_wait extension.
|
||||
*/
|
||||
|
|
@ -68,5 +68,5 @@ private:
|
|||
VkResult wait_for_update(uint64_t present_id, uint64_t timeout_in_ns) override;
|
||||
};
|
||||
|
||||
} /* namespace wayland */
|
||||
} /* namespace display */
|
||||
} /* namespace wsi */
|
||||
|
|
|
|||
|
|
@ -101,7 +101,6 @@ VkResult swapchain::add_required_extensions(VkDevice device, const VkSwapchainCr
|
|||
}
|
||||
}
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
if (m_device_data.is_present_wait_enabled())
|
||||
{
|
||||
if (!add_swapchain_extension(
|
||||
|
|
@ -110,7 +109,6 @@ VkResult swapchain::add_required_extensions(VkDevice device, const VkSwapchainCr
|
|||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,28 +41,66 @@ void wsi_ext_present_id::mark_delivered(uint64_t present_id)
|
|||
std::unique_lock lock(m_mutex);
|
||||
m_last_delivered_id.store(present_id, std::memory_order_relaxed);
|
||||
}
|
||||
m_present_id_changed.notify_all();
|
||||
m_present_state_changed.notify_all();
|
||||
}
|
||||
|
||||
bool wsi_ext_present_id::wait_for_present_id(uint64_t present_id, uint64_t timeout_in_ns)
|
||||
void wsi_ext_present_id::set_error_state(VkResult error_code)
|
||||
{
|
||||
std::unique_lock lock(m_mutex);
|
||||
m_error_state.store(error_code);
|
||||
m_present_state_changed.notify_all();
|
||||
}
|
||||
|
||||
VkResult wsi_ext_present_id::get_error_state()
|
||||
{
|
||||
return m_error_state;
|
||||
}
|
||||
|
||||
VkResult wsi_ext_present_id::wait_for_present_id(uint64_t present_id, uint64_t timeout_in_ns)
|
||||
{
|
||||
if (m_last_delivered_id.load() >= present_id)
|
||||
{
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
std::unique_lock lock(m_mutex);
|
||||
try
|
||||
{
|
||||
return m_present_id_changed.wait_for(lock, std::chrono::nanoseconds(timeout_in_ns),
|
||||
[&]() { return m_last_delivered_id.load() >= present_id; });
|
||||
std::unique_lock lock(m_mutex);
|
||||
if (timeout_in_ns == UINT64_MAX)
|
||||
{
|
||||
/* Infinite wait */
|
||||
m_present_state_changed.wait(
|
||||
lock, [&]() { return (m_last_delivered_id.load() >= present_id || m_error_state.load() != VK_SUCCESS); });
|
||||
|
||||
/* The condition can either return when present_id condition has been reached or there has been an error */
|
||||
return m_error_state;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Note: With very long timeouts it is possible that the clock in condition_variable will overflow.
|
||||
* This will result in wait_for immediately returning with a failed result. Considering the
|
||||
* duration needed to overflow the clock, we can probably ignore this. */
|
||||
bool wait_success = m_present_state_changed.wait_for(lock, std::chrono::nanoseconds(timeout_in_ns), [&]() {
|
||||
return (m_last_delivered_id.load() >= present_id || m_error_state.load() != VK_SUCCESS);
|
||||
});
|
||||
|
||||
if (!wait_success)
|
||||
{
|
||||
/* We timed out */
|
||||
return VK_TIMEOUT;
|
||||
}
|
||||
|
||||
/* The condition can either return when present_id condition has been reached or there has been an error */
|
||||
return m_error_state;
|
||||
}
|
||||
}
|
||||
catch (const std::system_error &e)
|
||||
{
|
||||
WSI_LOG_ERROR("Failed to wait for conditional variable. Code: %d, message: %s\n", e.code().value(), e.what());
|
||||
}
|
||||
|
||||
return false;
|
||||
/* The mutex lock has failed */
|
||||
return VK_ERROR_SURFACE_LOST_KHR;
|
||||
}
|
||||
|
||||
uint64_t wsi_ext_present_id::get_last_delivered_present_id() const
|
||||
|
|
|
|||
|
|
@ -60,15 +60,32 @@ public:
|
|||
*/
|
||||
void mark_delivered(uint64_t present_id);
|
||||
|
||||
/**
|
||||
* @brief Sets the error state for all pending and future image requests.
|
||||
* Any error state other than VK_SUCCESS will cause all current and
|
||||
* future calls to vkWaitForPresentKHR to fail with @p error_code.
|
||||
*
|
||||
* @param error_code Vulkan error code
|
||||
*/
|
||||
void set_error_state(VkResult error_code);
|
||||
|
||||
/**
|
||||
* @brief Get the current error state
|
||||
*
|
||||
* @return VkResult error state
|
||||
*/
|
||||
VkResult get_error_state();
|
||||
|
||||
/**
|
||||
* @brief Waits for present ID to be above or equal to the @p value.
|
||||
*
|
||||
* @param value The value to wait for.
|
||||
* @param present_id The value to wait for.
|
||||
* @param timeout_in_ns Timeout in nanoseconds.
|
||||
* @return true The present ID value is equal or higher than @p value
|
||||
* @return false The present ID is lower than @p value and timeout occured
|
||||
* @return VK_SUCCESS The present ID value is equal or higher than @p present_id
|
||||
* and there were no errors during present.
|
||||
* Any other error code to indicate a timeout or error state for the present.
|
||||
*/
|
||||
bool wait_for_present_id(uint64_t present_id, uint64_t timeout_in_ns);
|
||||
VkResult wait_for_present_id(uint64_t present_id, uint64_t timeout_in_ns);
|
||||
|
||||
/**
|
||||
* @brief Get the last delivered present ID value.
|
||||
|
|
@ -83,12 +100,17 @@ private:
|
|||
std::atomic<uint64_t> m_last_delivered_id{ 0 };
|
||||
|
||||
/**
|
||||
* @brief Conditional variable that notifies whenever present ID value has changed.
|
||||
* @brief Current error state of the swapchain
|
||||
*/
|
||||
std::condition_variable m_present_id_changed;
|
||||
std::atomic<VkResult> m_error_state{ VK_SUCCESS };
|
||||
|
||||
/**
|
||||
* @brief Mutex for m_present_id_changed conditional variable.
|
||||
* @brief Conditional variable that notifies whenever present state has changed.
|
||||
*/
|
||||
std::condition_variable m_present_state_changed;
|
||||
|
||||
/**
|
||||
* @brief Mutex for m_present_state_changed conditional variable.
|
||||
*/
|
||||
std::mutex m_mutex;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -41,7 +41,12 @@ wsi_ext_present_wait::wsi_ext_present_wait(wsi_ext_present_id &present_id_extens
|
|||
|
||||
VkResult wsi_ext_present_wait::wait_for_present_id(uint64_t present_id, uint64_t timeout_in_ns)
|
||||
{
|
||||
if (m_present_id_ext.get_last_delivered_present_id() >= present_id)
|
||||
VkResult error_state = m_present_id_ext.get_error_state();
|
||||
if (error_state != VK_SUCCESS)
|
||||
{
|
||||
return error_state;
|
||||
}
|
||||
else if (m_present_id_ext.get_last_delivered_present_id() >= present_id)
|
||||
{
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ wsi_ext_present_wait_headless::wsi_ext_present_wait_headless(wsi_ext_present_id
|
|||
|
||||
VkResult wsi_ext_present_wait_headless::wait_for_update(uint64_t present_id, uint64_t timeout_in_ns)
|
||||
{
|
||||
return m_present_id_ext.wait_for_present_id(present_id, timeout_in_ns) ? VK_SUCCESS : VK_TIMEOUT;
|
||||
return m_present_id_ext.wait_for_present_id(present_id, timeout_in_ns);
|
||||
}
|
||||
|
||||
} /* namespace wayland */
|
||||
} /* namespace headless */
|
||||
} /* namespace wsi */
|
||||
|
|
@ -109,7 +109,6 @@ VkResult swapchain::add_required_extensions(VkDevice device, const VkSwapchainCr
|
|||
}
|
||||
#endif
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
if (m_device_data.is_present_wait_enabled())
|
||||
{
|
||||
if (!add_swapchain_extension(m_allocator.make_unique<wsi_ext_present_wait_headless>(
|
||||
|
|
@ -118,7 +117,6 @@ VkResult swapchain::add_required_extensions(VkDevice device, const VkSwapchainCr
|
|||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,15 +41,17 @@
|
|||
#include <util/ring_buffer.hpp>
|
||||
#include <util/timed_semaphore.hpp>
|
||||
#include <util/log.hpp>
|
||||
#include <util/macros.hpp>
|
||||
|
||||
#include <layer/private_data.hpp>
|
||||
|
||||
#include "surface_properties.hpp"
|
||||
#include "synchronization.hpp"
|
||||
#include "swapchain_image_creator.hpp"
|
||||
|
||||
#include "extensions/frame_boundary.hpp"
|
||||
#include "extensions/wsi_extension.hpp"
|
||||
#include "swapchain_image_creator.hpp"
|
||||
#include "util/macros.hpp"
|
||||
#include "extensions/present_id.hpp"
|
||||
|
||||
namespace wsi
|
||||
{
|
||||
|
|
@ -630,6 +632,12 @@ protected:
|
|||
void set_error_state(VkResult state)
|
||||
{
|
||||
m_error_state = state;
|
||||
|
||||
auto *ext = get_swapchain_extension<wsi_ext_present_id>();
|
||||
if (ext)
|
||||
{
|
||||
ext->set_error_state(state);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -60,7 +60,12 @@ VkResult wsi_ext_present_wait_wayland::wait_for_update(uint64_t present_id, uint
|
|||
|
||||
do
|
||||
{
|
||||
if (m_present_id_ext.get_last_delivered_present_id() >= present_id)
|
||||
VkResult error_state = m_present_id_ext.get_error_state();
|
||||
if (error_state != VK_SUCCESS)
|
||||
{
|
||||
return error_state;
|
||||
}
|
||||
else if (m_present_id_ext.get_last_delivered_present_id() >= present_id)
|
||||
{
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,7 +112,6 @@ VkResult swapchain::add_required_extensions(VkDevice device, const VkSwapchainCr
|
|||
}
|
||||
}
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
if (m_device_data.is_present_wait_enabled())
|
||||
{
|
||||
if (!add_swapchain_extension(
|
||||
|
|
@ -121,7 +120,6 @@ VkResult swapchain::add_required_extensions(VkDevice device, const VkSwapchainCr
|
|||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_device_data.should_layer_handle_frame_boundary_events())
|
||||
{
|
||||
|
|
@ -200,13 +198,11 @@ VkResult swapchain::init_platform(VkDevice device, const VkSwapchainCreateInfoKH
|
|||
#endif
|
||||
&& (m_present_mode != VK_PRESENT_MODE_MAILBOX_KHR);
|
||||
|
||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||
auto present_wait = get_swapchain_extension<wsi_ext_present_wait_wayland>();
|
||||
if (present_wait)
|
||||
{
|
||||
present_wait->set_wayland_dispatcher(m_display, m_buffer_queue);
|
||||
}
|
||||
#endif
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,12 @@ namespace wsi
|
|||
namespace wayland
|
||||
{
|
||||
|
||||
VWL_CAPI_CALL(void)
|
||||
wp_presentation_feedback_sync_output(void *, struct wp_presentation_feedback *, struct wl_output *)
|
||||
{
|
||||
/* Not relevant */
|
||||
}
|
||||
|
||||
VWL_CAPI_CALL(void)
|
||||
wp_presentation_feedback_presented(void *data, struct wp_presentation_feedback *, uint32_t, uint32_t, uint32_t,
|
||||
uint32_t, uint32_t, uint32_t, uint32_t)
|
||||
|
|
@ -42,10 +48,24 @@ wp_presentation_feedback_presented(void *data, struct wp_presentation_feedback *
|
|||
}
|
||||
}
|
||||
|
||||
VWL_CAPI_CALL(void)
|
||||
wp_presentation_feedback_discarded(void *data, struct wp_presentation_feedback *)
|
||||
{
|
||||
/* If the presentation request has been discarded, we still want to notify that the image has reached the compositor
|
||||
* as otherwise, any functions waiting on the present ID will never be notified. There is nothing more we can do
|
||||
* with this request as it has been discarded. */
|
||||
auto feedback_obj = reinterpret_cast<wsi::wayland::presentation_feedback *>(data);
|
||||
if (feedback_obj->ext() != nullptr)
|
||||
{
|
||||
feedback_obj->ext()->mark_delivered(feedback_obj->present_id());
|
||||
feedback_obj->ext()->remove_from_pending_present_feedback_list(feedback_obj->present_id());
|
||||
}
|
||||
}
|
||||
|
||||
static const wp_presentation_feedback_listener presentation_listener = {
|
||||
.sync_output = NULL,
|
||||
.sync_output = wp_presentation_feedback_sync_output,
|
||||
.presented = wp_presentation_feedback_presented,
|
||||
.discarded = NULL,
|
||||
.discarded = wp_presentation_feedback_discarded,
|
||||
};
|
||||
|
||||
VkResult register_wp_presentation_feedback_listener(struct wp_presentation_feedback *wp_presentation_feedback,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue