Add vkGetSwapchainTimeDomainPropertiesEXT support

This commit is contained in:
Angeliki Agathi Tsintzira 2024-11-15 12:49:31 +00:00 committed by Iason Paraskevopoulos
parent d0671474e5
commit 3051ca8b67
12 changed files with 363 additions and 73 deletions

View file

@ -275,6 +275,7 @@ add_library(${PROJECT_NAME} SHARED
wsi/wsi_factory.cpp) wsi/wsi_factory.cpp)
if (VULKAN_WSI_LAYER_EXPERIMENTAL) if (VULKAN_WSI_LAYER_EXPERIMENTAL)
target_sources(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/layer/present_timing.cpp) target_sources(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/layer/present_timing.cpp)
target_sources(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/wsi/time_domains.cpp)
add_definitions("-DVULKAN_WSI_LAYER_EXPERIMENTAL=1") add_definitions("-DVULKAN_WSI_LAYER_EXPERIMENTAL=1")
else() else()
list(APPEND JSON_COMMANDS COMMAND sed -i '/VK_EXT_present_timing/d' ${CMAKE_CURRENT_BINARY_DIR}/VkLayer_window_system_integration.json) list(APPEND JSON_COMMANDS COMMAND sed -i '/VK_EXT_present_timing/d' ${CMAKE_CURRENT_BINARY_DIR}/VkLayer_window_system_integration.json)

View file

@ -534,7 +534,7 @@ wsi_layer_vkGetDeviceProcAddr(VkDevice device, const char *funcName) VWL_API_POS
GET_PROC_ADDR(vkGetSwapchainStatusKHR); GET_PROC_ADDR(vkGetSwapchainStatusKHR);
} }
#if VULKAN_WSI_LAYER_EXPERIMENTAL #if VULKAN_WSI_LAYER_EXPERIMENTAL
if (layer::device_private_data::get(device).is_device_extension_enabled(VK_KHR_PRESENT_TIMING_EXTENSION_NAME)) if (layer::device_private_data::get(device).is_device_extension_enabled(VK_EXT_PRESENT_TIMING_EXTENSION_NAME))
{ {
GET_PROC_ADDR(vkSetSwapchainPresentTimingQueueSizeEXT); GET_PROC_ADDR(vkSetSwapchainPresentTimingQueueSizeEXT);
GET_PROC_ADDR(vkGetSwapchainTimingPropertiesEXT); GET_PROC_ADDR(vkGetSwapchainTimingPropertiesEXT);

View file

@ -64,8 +64,15 @@ wsi_layer_vkGetSwapchainTimeDomainPropertiesEXT(
VkDevice device, VkSwapchainKHR swapchain, uint64_t *pTimeDomainsCounter, VkDevice device, VkSwapchainKHR swapchain, uint64_t *pTimeDomainsCounter,
VkSwapchainTimeDomainPropertiesEXT *pSwapchainTimeDomainProperties) VWL_API_POST VkSwapchainTimeDomainPropertiesEXT *pSwapchainTimeDomainProperties) VWL_API_POST
{ {
VkResult result = VK_SUCCESS; auto &device_data = layer::device_private_data::get(device);
return result;
if (!device_data.layer_owns_swapchain(swapchain))
{
return device_data.disp.GetSwapchainTimeDomainPropertiesEXT(device, swapchain, pTimeDomainsCounter,
pSwapchainTimeDomainProperties);
}
auto *sc = reinterpret_cast<wsi::swapchain_base *>(swapchain);
return sc->set_swapchain_time_domain_properties(pSwapchainTimeDomainProperties, pTimeDomainsCounter);
} }
/** /**

View file

@ -50,7 +50,12 @@ VkResult instance_dispatch_table::populate(VkInstance instance, PFN_vkGetInstanc
{ "vk" #name, ext_name, nullptr, api_version, false, required }, { "vk" #name, ext_name, nullptr, api_version, false, required },
INSTANCE_ENTRYPOINTS_LIST(DISPATCH_TABLE_ENTRY) INSTANCE_ENTRYPOINTS_LIST(DISPATCH_TABLE_ENTRY)
#undef DISPATCH_TABLE_ENTRY #undef DISPATCH_TABLE_ENTRY
#if VULKAN_WSI_LAYER_EXPERIMENTAL
{ "GetSwapchainTimeDomainPropertiesEXT", VK_EXT_PRESENT_TIMING_EXTENSION_NAME, nullptr, API_VERSION_MAX, false,
false }
#endif /* VULKAN_WSI_LAYER_EXPERIMENTAL */
}; };
static constexpr auto num_entrypoints = std::distance(std::begin(entrypoints_init), std::end(entrypoints_init)); static constexpr auto num_entrypoints = std::distance(std::begin(entrypoints_init), std::end(entrypoints_init));
for (size_t i = 0; i < num_entrypoints; i++) for (size_t i = 0; i < num_entrypoints; i++)

View file

@ -41,7 +41,7 @@
#include <mutex> #include <mutex>
#include <limits> #include <limits>
#include <cstring> #include <cstring>
#include "wsi_layer_experimental.hpp"
using scoped_mutex = std::lock_guard<std::mutex>; using scoped_mutex = std::lock_guard<std::mutex>;
/** Forward declare stored objects */ /** Forward declare stored objects */
@ -339,72 +339,69 @@ private:
* api_version: Vulkan API version where the entrypoint is part of the core specification, or API_VERSION_MAX. * api_version: Vulkan API version where the entrypoint is part of the core specification, or API_VERSION_MAX.
* required: Boolean to indicate whether the entrypoint is required by the WSI layer or optional. * required: Boolean to indicate whether the entrypoint is required by the WSI layer or optional.
*/ */
#define DEVICE_ENTRYPOINTS_LIST(EP) \ #define DEVICE_ENTRYPOINTS_LIST(EP) \
/* Vulkan 1.0 */ \ /* Vulkan 1.0 */ \
EP(GetDeviceProcAddr, "", VK_API_VERSION_1_0, true) \ EP(GetDeviceProcAddr, "", VK_API_VERSION_1_0, true) \
EP(GetDeviceQueue, "", VK_API_VERSION_1_0, true) \ EP(GetDeviceQueue, "", VK_API_VERSION_1_0, true) \
EP(QueueSubmit, "", VK_API_VERSION_1_0, true) \ EP(QueueSubmit, "", VK_API_VERSION_1_0, true) \
EP(QueueWaitIdle, "", VK_API_VERSION_1_0, true) \ EP(QueueWaitIdle, "", VK_API_VERSION_1_0, true) \
EP(CreateCommandPool, "", VK_API_VERSION_1_0, true) \ EP(CreateCommandPool, "", VK_API_VERSION_1_0, true) \
EP(DestroyCommandPool, "", VK_API_VERSION_1_0, true) \ EP(DestroyCommandPool, "", VK_API_VERSION_1_0, true) \
EP(AllocateCommandBuffers, "", VK_API_VERSION_1_0, true) \ EP(AllocateCommandBuffers, "", VK_API_VERSION_1_0, true) \
EP(FreeCommandBuffers, "", VK_API_VERSION_1_0, true) \ EP(FreeCommandBuffers, "", VK_API_VERSION_1_0, true) \
EP(ResetCommandBuffer, "", VK_API_VERSION_1_0, true) \ EP(ResetCommandBuffer, "", VK_API_VERSION_1_0, true) \
EP(BeginCommandBuffer, "", VK_API_VERSION_1_0, true) \ EP(BeginCommandBuffer, "", VK_API_VERSION_1_0, true) \
EP(EndCommandBuffer, "", VK_API_VERSION_1_0, true) \ EP(EndCommandBuffer, "", VK_API_VERSION_1_0, true) \
EP(CreateImage, "", VK_API_VERSION_1_0, true) \ EP(CreateImage, "", VK_API_VERSION_1_0, true) \
EP(DestroyImage, "", VK_API_VERSION_1_0, true) \ EP(DestroyImage, "", VK_API_VERSION_1_0, true) \
EP(GetImageMemoryRequirements, "", VK_API_VERSION_1_0, true) \ EP(GetImageMemoryRequirements, "", VK_API_VERSION_1_0, true) \
EP(BindImageMemory, "", VK_API_VERSION_1_0, true) \ EP(BindImageMemory, "", VK_API_VERSION_1_0, true) \
EP(AllocateMemory, "", VK_API_VERSION_1_0, true) \ EP(AllocateMemory, "", VK_API_VERSION_1_0, true) \
EP(FreeMemory, "", VK_API_VERSION_1_0, true) \ EP(FreeMemory, "", VK_API_VERSION_1_0, true) \
EP(CreateFence, "", VK_API_VERSION_1_0, true) \ EP(CreateFence, "", VK_API_VERSION_1_0, true) \
EP(DestroyFence, "", VK_API_VERSION_1_0, true) \ EP(DestroyFence, "", VK_API_VERSION_1_0, true) \
EP(CreateSemaphore, "", VK_API_VERSION_1_0, true) \ EP(CreateSemaphore, "", VK_API_VERSION_1_0, true) \
EP(DestroySemaphore, "", VK_API_VERSION_1_0, true) \ EP(DestroySemaphore, "", VK_API_VERSION_1_0, true) \
EP(ResetFences, "", VK_API_VERSION_1_0, true) \ EP(ResetFences, "", VK_API_VERSION_1_0, true) \
EP(WaitForFences, "", VK_API_VERSION_1_0, true) \ EP(WaitForFences, "", VK_API_VERSION_1_0, true) \
EP(DestroyDevice, "", VK_API_VERSION_1_0, true) \ EP(DestroyDevice, "", VK_API_VERSION_1_0, true) \
/* VK_KHR_swapchain */ \ /* VK_KHR_swapchain */ \
EP(CreateSwapchainKHR, VK_KHR_SWAPCHAIN_EXTENSION_NAME, API_VERSION_MAX, false) \ EP(CreateSwapchainKHR, VK_KHR_SWAPCHAIN_EXTENSION_NAME, API_VERSION_MAX, false) \
EP(DestroySwapchainKHR, VK_KHR_SWAPCHAIN_EXTENSION_NAME, API_VERSION_MAX, false) \ EP(DestroySwapchainKHR, VK_KHR_SWAPCHAIN_EXTENSION_NAME, API_VERSION_MAX, false) \
EP(GetSwapchainImagesKHR, VK_KHR_SWAPCHAIN_EXTENSION_NAME, API_VERSION_MAX, false) \ EP(GetSwapchainImagesKHR, VK_KHR_SWAPCHAIN_EXTENSION_NAME, API_VERSION_MAX, false) \
EP(AcquireNextImageKHR, VK_KHR_SWAPCHAIN_EXTENSION_NAME, API_VERSION_MAX, false) \ EP(AcquireNextImageKHR, VK_KHR_SWAPCHAIN_EXTENSION_NAME, API_VERSION_MAX, false) \
EP(QueuePresentKHR, VK_KHR_SWAPCHAIN_EXTENSION_NAME, API_VERSION_MAX, false) \ EP(QueuePresentKHR, VK_KHR_SWAPCHAIN_EXTENSION_NAME, API_VERSION_MAX, false) \
/* VK_KHR_shared_presentable_image */ \ /* VK_KHR_shared_presentable_image */ \
EP(GetSwapchainStatusKHR, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, API_VERSION_MAX, false) \ EP(GetSwapchainStatusKHR, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, API_VERSION_MAX, false) \
/* VK_KHR_device_group + VK_KHR_swapchain or */ \ /* VK_KHR_device_group + VK_KHR_swapchain or */ /* 1.1 with VK_KHR_swapchain */ \
/* 1.1 with VK_KHR_swapchain */ \ EP(AcquireNextImage2KHR, VK_KHR_DEVICE_GROUP_EXTENSION_NAME, VK_API_VERSION_1_1, false) \
EP(AcquireNextImage2KHR, VK_KHR_DEVICE_GROUP_EXTENSION_NAME, VK_API_VERSION_1_1, false) \ /* VK_KHR_device_group + VK_KHR_surface or */ /* 1.1 with VK_KHR_swapchain */ \
/* VK_KHR_device_group + VK_KHR_surface or */ \ EP(GetDeviceGroupSurfacePresentModesKHR, VK_KHR_DEVICE_GROUP_EXTENSION_NAME, VK_API_VERSION_1_1, false) \
/* 1.1 with VK_KHR_swapchain */ \ EP(GetDeviceGroupPresentCapabilitiesKHR, VK_KHR_DEVICE_GROUP_EXTENSION_NAME, VK_API_VERSION_1_1, \
EP(GetDeviceGroupSurfacePresentModesKHR, VK_KHR_DEVICE_GROUP_EXTENSION_NAME, VK_API_VERSION_1_1, false) \ false) /* VK_KHR_external_memory_fd */ \
EP(GetDeviceGroupPresentCapabilitiesKHR, VK_KHR_DEVICE_GROUP_EXTENSION_NAME, VK_API_VERSION_1_1, false) \ EP(GetMemoryFdKHR, VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, API_VERSION_MAX, false) \
/* VK_KHR_external_memory_fd */ \ EP(GetMemoryFdPropertiesKHR, VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, API_VERSION_MAX, false) \
EP(GetMemoryFdKHR, VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, API_VERSION_MAX, false) \ /* VK_KHR_bind_memory2 or */ /* 1.1 (without KHR suffix) */ \
EP(GetMemoryFdPropertiesKHR, VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, API_VERSION_MAX, false) \ EP(BindImageMemory2KHR, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, VK_API_VERSION_1_1, false) \
/* VK_KHR_bind_memory2 or */ \ EP(BindBufferMemory2KHR, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, VK_API_VERSION_1_1, \
/* 1.1 (without KHR suffix) */ \ false) /* VK_KHR_external_fence_fd */ \
EP(BindImageMemory2KHR, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, VK_API_VERSION_1_1, false) \ EP(GetFenceFdKHR, VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME, API_VERSION_MAX, false) \
EP(BindBufferMemory2KHR, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, VK_API_VERSION_1_1, false) \ EP(ImportFenceFdKHR, VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME, API_VERSION_MAX, \
/* VK_KHR_external_fence_fd */ \ false) /* VK_KHR_external_semaphore_fd */ \
EP(GetFenceFdKHR, VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME, API_VERSION_MAX, false) \ EP(ImportSemaphoreFdKHR, VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, API_VERSION_MAX, false) \
EP(ImportFenceFdKHR, VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME, API_VERSION_MAX, false) \ EP(GetSemaphoreFdKHR, VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, API_VERSION_MAX, \
/* VK_KHR_external_semaphore_fd */ \ false) /* VK_KHR_image_drm_format_modifier */ \
EP(ImportSemaphoreFdKHR, VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, API_VERSION_MAX, false) \ EP(GetImageDrmFormatModifierPropertiesEXT, VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME, API_VERSION_MAX, \
EP(GetSemaphoreFdKHR, VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, API_VERSION_MAX, false) \ false) /* VK_KHR_sampler_ycbcr_conversion */ \
/* VK_KHR_image_drm_format_modifier */ \ EP(CreateSamplerYcbcrConversionKHR, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, VK_API_VERSION_1_1, false) \
EP(GetImageDrmFormatModifierPropertiesEXT, VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME, API_VERSION_MAX, false) \ EP(DestroySamplerYcbcrConversionKHR, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, VK_API_VERSION_1_1, \
/* VK_KHR_sampler_ycbcr_conversion */ \ false) /* VK_KHR_maintenance1 */ \
EP(CreateSamplerYcbcrConversionKHR, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, VK_API_VERSION_1_1, false) \ EP(TrimCommandPoolKHR, VK_KHR_MAINTENANCE1_EXTENSION_NAME, VK_API_VERSION_1_1, \
EP(DestroySamplerYcbcrConversionKHR, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, VK_API_VERSION_1_1, false) \ false) /* VK_KHR_get_memory_requirements2 */ \
/* VK_KHR_maintenance1 */ \ EP(GetImageMemoryRequirements2KHR, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, VK_API_VERSION_1_1, false) \
EP(TrimCommandPoolKHR, VK_KHR_MAINTENANCE1_EXTENSION_NAME, VK_API_VERSION_1_1, false) \ EP(GetBufferMemoryRequirements2KHR, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, VK_API_VERSION_1_1, false) \
/* VK_KHR_get_memory_requirements2 */ \ EP(GetImageSparseMemoryRequirements2KHR, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, VK_API_VERSION_1_1, \
EP(GetImageMemoryRequirements2KHR, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, VK_API_VERSION_1_1, false) \ false) \
EP(GetBufferMemoryRequirements2KHR, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, VK_API_VERSION_1_1, false) \
EP(GetImageSparseMemoryRequirements2KHR, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, VK_API_VERSION_1_1, \
false) \
EP(ReleaseSwapchainImagesEXT, VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME, VK_API_VERSION_1_1, false) EP(ReleaseSwapchainImagesEXT, VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME, VK_API_VERSION_1_1, false)
/** /**
@ -461,6 +458,15 @@ public:
DEVICE_ENTRYPOINTS_LIST(DISPATCH_TABLE_SHORTCUT) DEVICE_ENTRYPOINTS_LIST(DISPATCH_TABLE_SHORTCUT)
#undef DISPATCH_TABLE_SHORTCUT #undef DISPATCH_TABLE_SHORTCUT
#if VULKAN_WSI_LAYER_EXPERIMENTAL
template <class... Args>
auto GetSwapchainTimeDomainPropertiesEXT(Args &&...args) const
{
return call_fn<PFN_vkGetSwapchainTimeDomainPropertiesEXT>("vkGetSwapchainTimeDomainPropertiesEXT",
std::forward<Args>(args)...);
};
#endif
private: private:
/** /**
* @brief Construct instance dispatch table object * @brief Construct instance dispatch table object

View file

@ -33,9 +33,9 @@
#include "util/macros.hpp" #include "util/macros.hpp"
#if VULKAN_WSI_LAYER_EXPERIMENTAL #if VULKAN_WSI_LAYER_EXPERIMENTAL
#define VK_KHR_present_timing 1 #define VK_EXT_present_timing 1
#define VK_KHR_PRESENT_TIMING_SPEC_VERSION 1 #define VK_EXT_PRESENT_TIMING_SPEC_VERSION 1
#define VK_KHR_PRESENT_TIMING_EXTENSION_NAME "VK_KHR_present_timing" #define VK_EXT_PRESENT_TIMING_EXTENSION_NAME "VK_KHR_present_timing"
#define VK_ERROR_PRESENT_TIMING_QUEUE_FULL_EXT ((VkResult)(-1000208000)) #define VK_ERROR_PRESENT_TIMING_QUEUE_FULL_EXT ((VkResult)(-1000208000))
#define VK_TIME_DOMAIN_PRESENT_STAGE_LOCAL_EXT ((VkTimeDomainEXT)(1000208000)) #define VK_TIME_DOMAIN_PRESENT_STAGE_LOCAL_EXT ((VkTimeDomainEXT)(1000208000))
@ -168,6 +168,10 @@ typedef struct VkPresentTimingsInfoEXT
const VkPresentTimingInfoEXT *pTimingInfos; const VkPresentTimingInfoEXT *pTimingInfos;
} VkPresentTimingsInfoEXT; } VkPresentTimingsInfoEXT;
typedef VkResult(VKAPI_PTR *PFN_vkGetSwapchainTimeDomainPropertiesEXT)(
VkDevice device, VkSwapchainKHR swapchain, uint64_t *pTimeDomainsCounter,
VkSwapchainTimeDomainPropertiesEXT *pSwapchainTimeDomainProperties);
VWL_VKAPI_CALL(VkResult) VWL_VKAPI_CALL(VkResult)
wsi_layer_vkSetSwapchainPresentTimingQueueSizeEXT(VkDevice device, VkSwapchainKHR swapchain, wsi_layer_vkSetSwapchainPresentTimingQueueSizeEXT(VkDevice device, VkSwapchainKHR swapchain,
uint32_t size) VWL_API_POST; uint32_t size) VWL_API_POST;

View file

@ -34,6 +34,8 @@
#include <util/timed_semaphore.hpp> #include <util/timed_semaphore.hpp>
#include "swapchain.hpp" #include "swapchain.hpp"
#include "layer/wsi_layer_experimental.hpp"
#include "util/custom_allocator.hpp"
namespace wsi namespace wsi
{ {
@ -72,6 +74,27 @@ VkResult swapchain::init_platform(VkDevice device, const VkSwapchainCreateInfoKH
{ {
use_presentation_thread = true; use_presentation_thread = true;
} }
#if VULKAN_WSI_LAYER_EXPERIMENTAL
std::array<util::unique_ptr<wsi::vulkan_time_domain>, 4> time_domains_array = {
m_allocator.make_unique<wsi::vulkan_time_domain>(VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT,
VK_TIME_DOMAIN_DEVICE_KHR),
m_allocator.make_unique<wsi::vulkan_time_domain>(VK_PRESENT_STAGE_IMAGE_LATCHED_BIT_EXT,
VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR),
m_allocator.make_unique<wsi::vulkan_time_domain>(VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT,
VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR),
m_allocator.make_unique<wsi::vulkan_time_domain>(VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_BIT_EXT,
VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR)
};
for (auto &time_domain : time_domains_array)
{
if (!m_time_domains.m_time_domains.try_push_back(std::move(time_domain)))
{
WSI_LOG_ERROR("Failed to add a time domain to m_time_domains.");
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
}
#endif
return VK_SUCCESS; return VK_SUCCESS;
} }

View file

@ -220,6 +220,9 @@ swapchain_base::swapchain_base(layer::device_private_data &dev_data, const VkAll
, m_image_compression_control_params({ VK_IMAGE_COMPRESSION_DEFAULT_EXT, 0 }) , m_image_compression_control_params({ VK_IMAGE_COMPRESSION_DEFAULT_EXT, 0 })
#endif #endif
, m_image_create_info() , m_image_create_info()
#if VULKAN_WSI_LAYER_EXPERIMENTAL
, m_time_domains(m_allocator)
#endif
, m_image_acquire_lock() , m_image_acquire_lock()
, m_error_state(VK_NOT_READY) , m_error_state(VK_NOT_READY)
, m_started_presenting(false) , m_started_presenting(false)
@ -916,6 +919,12 @@ size_t swapchain_base::presentation_timing_get_num_outstanding_results()
} }
return num_outstanding; return num_outstanding;
} }
VkResult swapchain_base::set_swapchain_time_domain_properties(
VkSwapchainTimeDomainPropertiesEXT *pSwapchainTimeDomainProperties, uint64_t *pTimeDomainsCounter)
{
return m_time_domains.set_swapchain_time_domain_properties(pSwapchainTimeDomainProperties, pTimeDomainsCounter);
}
#endif #endif
} /* namespace wsi */ } /* namespace wsi */

View file

@ -44,6 +44,8 @@
#include "wsi/synchronization.hpp" #include "wsi/synchronization.hpp"
#include "wsi/frame_boundary.hpp" #include "wsi/frame_boundary.hpp"
#include "util/helpers.hpp" #include "util/helpers.hpp"
#include "time_domains.hpp"
#include "layer/wsi_layer_experimental.hpp"
namespace wsi namespace wsi
{ {
@ -304,7 +306,18 @@ public:
* @return VK_SUCCESS on success, VK_ERROR_OUT_OF_HOST_MEMORY when there is not enough memory, VK_NOT_READY otherwise. * @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); VkResult presentation_timing_queue_set_size(size_t queue_size);
/**
* @brief Set swapchain time domain properties.
*
* @param pSwapchainTimeDomainProperties time domain struct to be set
* @param pTimeDomainsCounter size of the pSwapchainTimeDomainProperties
*
* @return Returns VK_SUCCESS on success, otherwise an appropriate error code.
*/
VkResult set_swapchain_time_domain_properties(VkSwapchainTimeDomainPropertiesEXT *pSwapchainTimeDomainProperties,
uint64_t *pTimeDomainsCounter);
#endif #endif
protected: protected:
@ -426,6 +439,13 @@ protected:
*/ */
VkImageCreateInfo m_image_create_info; VkImageCreateInfo m_image_create_info;
#if VULKAN_WSI_LAYER_EXPERIMENTAL
/**
* @brief Handle the backend specific time domains for each present stage.
*/
swapchain_time_domains m_time_domains;
#endif
/** /**
* @brief Return the VkAllocationCallbacks passed in this object constructor. * @brief Return the VkAllocationCallbacks passed in this object constructor.
*/ */

90
wsi/time_domains.cpp Normal file
View file

@ -0,0 +1,90 @@
/*
* Copyright (c) 2024 Arm Limited.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/**
* @file time_domains.cpp
*
* @brief Contains implemenations and details for the time domains per backend.
*/
#include "time_domains.hpp"
#include <vulkan/vulkan.h>
namespace wsi
{
#if VULKAN_WSI_LAYER_EXPERIMENTAL
VkResult swapchain_time_domains::calibrate(VkPresentStageFlagBitsEXT present_stage,
swapchain_calibrated_time *calibrated_time)
{
for (auto &domain : m_time_domains)
{
if ((domain->get_present_stages() & present_stage) != 0)
{
*calibrated_time = domain->calibrate();
return VK_SUCCESS;
}
}
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
VkResult swapchain_time_domains::set_swapchain_time_domain_properties(
VkSwapchainTimeDomainPropertiesEXT *pSwapchainTimeDomainProperties, uint64_t *pTimeDomainsCounter)
{
if (pTimeDomainsCounter != nullptr)
{
if (pSwapchainTimeDomainProperties == nullptr)
{
*pTimeDomainsCounter = 1;
return VK_SUCCESS;
}
pSwapchainTimeDomainProperties->timeDomainCount = 1;
pSwapchainTimeDomainProperties->pTimeDomains[0] = VK_TIME_DOMAIN_PRESENT_STAGE_LOCAL_EXT;
pSwapchainTimeDomainProperties->pTimeDomainIds = 0;
return (*pTimeDomainsCounter < 1) ? VK_INCOMPLETE : VK_SUCCESS;
}
if (pSwapchainTimeDomainProperties != nullptr)
{
if (pSwapchainTimeDomainProperties->pTimeDomains == nullptr &&
pSwapchainTimeDomainProperties->pTimeDomainIds == nullptr)
{
pSwapchainTimeDomainProperties->timeDomainCount = 1;
return VK_SUCCESS;
}
if (pSwapchainTimeDomainProperties->pTimeDomains != nullptr &&
pSwapchainTimeDomainProperties->pTimeDomainIds != nullptr)
{
pSwapchainTimeDomainProperties->timeDomainCount = 1;
pSwapchainTimeDomainProperties->pTimeDomains[0] = VK_TIME_DOMAIN_PRESENT_STAGE_LOCAL_EXT;
pSwapchainTimeDomainProperties->pTimeDomainIds = 0;
return VK_SUCCESS;
}
}
return VK_SUCCESS;
}
#endif
}

108
wsi/time_domains.hpp Normal file
View file

@ -0,0 +1,108 @@
/*
* Copyright (c) 2024 Arm Limited.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/**
* @file time_domains.hpp
*
* @brief Contains functions and details for the time domains per backend.
*/
#pragma once
#include <cstddef>
#include <vulkan/vulkan.h>
#include <array>
#include <vector>
#include <util/log.hpp>
#include "util/custom_allocator.hpp"
#include "layer/wsi_layer_experimental.hpp"
namespace wsi
{
#if VULKAN_WSI_LAYER_EXPERIMENTAL
// Predefined struct for calibrated time
struct swapchain_calibrated_time
{
VkTimeDomainKHR time_domain;
uint64_t offset;
};
// Base struct for swapchain time domain
class swapchain_time_domain
{
public:
swapchain_time_domain(VkPresentStageFlagsEXT presentStages)
: m_present_stages(presentStages)
{
}
virtual swapchain_calibrated_time calibrate() = 0;
VkPresentStageFlagsEXT get_present_stages()
{
return m_present_stages;
}
private:
VkPresentStageFlagsEXT m_present_stages;
};
class vulkan_time_domain : public swapchain_time_domain
{
public:
vulkan_time_domain(VkPresentStageFlagsEXT presentStages, VkTimeDomainKHR time_domain)
: swapchain_time_domain(presentStages)
, m_time_domain(time_domain)
{
}
/* The calibrate function should return a Vulkan time domain + an offset.*/
swapchain_calibrated_time calibrate() override
{
return { m_time_domain, 0 };
}
private:
VkTimeDomainKHR m_time_domain;
};
/* Class holding multiple time domains for a swapchain*/
class swapchain_time_domains
{
public:
swapchain_time_domains(const util::allocator &allocator)
: m_time_domains(allocator)
{
}
util::vector<util::unique_ptr<swapchain_time_domain>> m_time_domains;
VkResult calibrate(VkPresentStageFlagBitsEXT presentStages, swapchain_calibrated_time *calibrated_time);
VkResult set_swapchain_time_domain_properties(VkSwapchainTimeDomainPropertiesEXT *pSwapchainTimeDomainProperties,
uint64_t *pTimeDomainsCounter);
};
#endif
}

View file

@ -27,6 +27,7 @@
#include "swapchain.hpp" #include "swapchain.hpp"
#include "wl_helpers.hpp" #include "wl_helpers.hpp"
#include "surface_properties.hpp" #include "surface_properties.hpp"
#include "layer/wsi_layer_experimental.hpp"
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
@ -80,6 +81,22 @@ swapchain::~swapchain()
VkResult swapchain::init_platform(VkDevice device, const VkSwapchainCreateInfoKHR *swapchain_create_info, VkResult swapchain::init_platform(VkDevice device, const VkSwapchainCreateInfoKHR *swapchain_create_info,
bool &use_presentation_thread) bool &use_presentation_thread)
{ {
#if VULKAN_WSI_LAYER_EXPERIMENTAL
std::array<util::unique_ptr<wsi::vulkan_time_domain>, 1> time_domains_array = {
m_allocator.make_unique<wsi::vulkan_time_domain>(VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT,
VK_TIME_DOMAIN_DEVICE_KHR),
};
for (auto &time_domain : time_domains_array)
{
if (!m_time_domains.m_time_domains.try_push_back(std::move(time_domain)))
{
WSI_LOG_ERROR("Failed to add a time domain to m_time_domains.");
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
}
#endif
if ((m_display == nullptr) || (m_surface == nullptr) || (m_wsi_surface->get_dmabuf_interface() == nullptr)) if ((m_display == nullptr) || (m_surface == nullptr) || (m_wsi_surface->get_dmabuf_interface() == nullptr))
{ {
return VK_ERROR_INITIALIZATION_FAILED; return VK_ERROR_INITIALIZATION_FAILED;