Reset query pool on creation

Makes use of the VK_QUERY_POOL_CREATE_RESET_BIT_KHR when creating the
query pool. It disables present timing when VK_KHR_maintenance9 is not
supported by the device.

Signed-off-by: Iason Paraskevopoulos <iason.paraskevopoulos@arm.com>
Change-Id: I9d364050f0cd4a2be74e1b1d44cf3f6a0795e6f4
This commit is contained in:
Iason Paraskevopoulos 2025-10-17 15:02:40 +00:00
parent 8f90584f20
commit 3da272878d
12 changed files with 140 additions and 23 deletions

View file

@ -246,12 +246,48 @@ VKAPI_ATTR VkResult create_device(VkPhysicalDevice physicalDevice, const VkDevic
util::vector<const char *> modified_enabled_extensions{ allocator };
util::extension_list enabled_extensions{ allocator };
#if VULKAN_WSI_LAYER_EXPERIMENTAL
VkPhysicalDeviceMaintenance9FeaturesKHR maintenance9_features = {};
#endif /* VULKAN_WSI_LAYER_EXPERIMENTAL */
const util::wsi_platform_set &enabled_platforms = inst_data.get_enabled_platforms();
if (!enabled_platforms.empty())
{
TRY_LOG_CALL(enabled_extensions.add(pCreateInfo->ppEnabledExtensionNames, pCreateInfo->enabledExtensionCount));
TRY_LOG_CALL(wsi::add_device_extensions_required_by_layer(physicalDevice, enabled_platforms, enabled_extensions,
inst_data.api_version));
#if VULKAN_WSI_LAYER_EXPERIMENTAL
auto present_timing_supported = wsi::present_timing_dependencies_supported(physicalDevice);
if (std::holds_alternative<VkResult>(present_timing_supported))
{
return std::get<VkResult>(present_timing_supported);
}
if (std::get<bool>(present_timing_supported))
{
TRY_LOG_CALL(enabled_extensions.add(VK_KHR_MAINTENANCE_9_EXTENSION_NAME));
const auto *device_maintenance9_features = util::find_extension<VkPhysicalDeviceMaintenance9FeaturesKHR>(
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_9_FEATURES_KHR, pCreateInfo->pNext);
if (device_maintenance9_features)
{
if (device_maintenance9_features->maintenance9 == VK_FALSE)
{
/* We are taking the same risk with the frame boundary features below. */
auto *maintenance9_features_non_const =
const_cast<VkPhysicalDeviceMaintenance9FeaturesKHR *>(device_maintenance9_features);
maintenance9_features_non_const->maintenance9 = VK_TRUE;
}
}
else
{
maintenance9_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_9_FEATURES_KHR;
maintenance9_features.pNext = const_cast<void *>(modified_info.pNext);
maintenance9_features.maintenance9 = VK_TRUE;
modified_info.pNext = &maintenance9_features;
}
}
#endif /* VULKAN_WSI_LAYER_EXPERIMENTAL */
TRY_LOG_CALL(enabled_extensions.get_extension_strings(modified_enabled_extensions));
modified_info.ppEnabledExtensionNames = modified_enabled_extensions.data();

View file

@ -671,6 +671,12 @@ public:
*/
bool has_image_compression_support(VkPhysicalDevice phys_dev);
/**
* @brief Check if a physical device supports frame boundary.
*
* @param phys_dev The physical device to query.
* @return Whether frame boundary control is supported by the ICD.
*/
bool has_frame_boundary_support(VkPhysicalDevice phys_dev);
/**

View file

@ -567,7 +567,7 @@ bool surface_properties::is_surface_extension_enabled(const layer::instance_priv
}
#if VULKAN_WSI_LAYER_EXPERIMENTAL
VkResult surface_properties::get_present_timing_surface_caps(
VkResult surface_properties::get_present_timing_surface_caps_internal(
VkPhysicalDevice, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps)
{
present_timing_surface_caps->presentTimingSupported = VK_FALSE;

View file

@ -66,11 +66,6 @@ public:
bool is_surface_extension_enabled(const layer::instance_private_data &instance_data) override;
#if VULKAN_WSI_LAYER_EXPERIMENTAL
VkResult get_present_timing_surface_caps(
VkPhysicalDevice physical_device, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) override;
#endif
static surface_properties &get_instance();
bool is_compatible_present_modes(VkPresentModeKHR present_mode_a, VkPresentModeKHR present_mode_b) override;
@ -86,6 +81,11 @@ private:
void get_surface_present_scaling_and_gravity(VkSurfacePresentScalingCapabilitiesEXT *scaling_capabilities) override;
void populate_present_mode_compatibilities() override;
#if VULKAN_WSI_LAYER_EXPERIMENTAL
VkResult get_present_timing_surface_caps_internal(
VkPhysicalDevice physical_device, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) override;
#endif
};
} /* namespace display */

View file

@ -698,6 +698,42 @@ VkResult check_time_domain_support(VkPhysicalDevice physical_device, std::tuple<
return VK_SUCCESS;
}
std::variant<bool, VkResult> present_timing_dependencies_supported(VkPhysicalDevice physical_device)
{
auto &instance_data = layer::instance_private_data::get(physical_device);
util::vector<VkExtensionProperties> properties{ util::allocator(instance_data.get_allocator(),
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND) };
uint32_t count = 0;
TRY_LOG(instance_data.disp.EnumerateDeviceExtensionProperties(physical_device, nullptr, &count, nullptr),
"Failed to enumurate properties of available physical device extensions");
if (!properties.try_resize(count))
{
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
TRY_LOG(instance_data.disp.EnumerateDeviceExtensionProperties(physical_device, nullptr, &count, properties.data()),
"Failed to enumurate properties of available physical device extensions");
const bool maintenance9_supported =
std::find_if(properties.begin(), properties.end(), [](const VkExtensionProperties &ext) {
return strcmp(ext.extensionName, VK_KHR_MAINTENANCE_9_EXTENSION_NAME) == 0;
}) != properties.end();
if (!maintenance9_supported)
{
return false;
}
VkPhysicalDeviceMaintenance9FeaturesKHR maintenance9 = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_9_FEATURES_KHR, nullptr, VK_FALSE
};
VkPhysicalDeviceFeatures2KHR features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR, &maintenance9, {} };
instance_data.disp.GetPhysicalDeviceFeatures2KHR(physical_device, &features);
return maintenance9.maintenance9 != VK_FALSE;
}
} /* namespace wsi */
#endif /* VULKAN_WSI_LAYER_EXPERIMENTAL */

View file

@ -46,6 +46,7 @@
#include <optional>
#include <functional>
#include <cassert>
#include <variant>
#include "wsi_extension.hpp"
@ -350,9 +351,12 @@ public:
command_buffer = VK_NULL_HANDLE;
}
/* Allocate the command pool and query pool. */
VkQueryPoolCreateInfo query_pool_info = {
VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, nullptr, 0, VK_QUERY_TYPE_TIMESTAMP, num_images, 0
};
VkQueryPoolCreateInfo query_pool_info = { VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,
nullptr,
VK_QUERY_POOL_CREATE_RESET_BIT_KHR,
VK_QUERY_TYPE_TIMESTAMP,
num_images,
0 };
TRY_LOG_CALL(m_device.disp.CreateQueryPool(m_device.device, &query_pool_info,
m_allocator.get_original_callbacks(), &m_query_pool));
VkCommandPoolCreateInfo command_pool_info{ VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, nullptr,
@ -778,5 +782,6 @@ private:
VkResult check_time_domain_support(VkPhysicalDevice physical_device, std::tuple<VkTimeDomainEXT, bool> *domains,
size_t domain_size);
std::variant<bool, VkResult> present_timing_dependencies_supported(VkPhysicalDevice physical_device);
} /* namespace wsi */
#endif

View file

@ -241,7 +241,7 @@ bool surface_properties::is_compatible_present_modes(VkPresentModeKHR present_mo
}
#if VULKAN_WSI_LAYER_EXPERIMENTAL
VkResult surface_properties::get_present_timing_surface_caps(
VkResult surface_properties::get_present_timing_surface_caps_internal(
VkPhysicalDevice physical_device, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps)
{
present_timing_surface_caps->presentTimingSupported = VK_TRUE;

View file

@ -64,11 +64,6 @@ public:
bool is_compatible_present_modes(VkPresentModeKHR present_mode_a, VkPresentModeKHR present_mode_b) override;
#if VULKAN_WSI_LAYER_EXPERIMENTAL
VkResult get_present_timing_surface_caps(
VkPhysicalDevice physical_device, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) override;
#endif
private:
/* List of supported presentation modes */
std::array<VkPresentModeKHR, PRESENT_MODES_NUM> m_supported_modes;
@ -79,6 +74,11 @@ private:
void populate_present_mode_compatibilities() override;
void get_surface_present_scaling_and_gravity(VkSurfacePresentScalingCapabilitiesEXT *scaling_capabilities) override;
#if VULKAN_WSI_LAYER_EXPERIMENTAL
VkResult get_present_timing_surface_caps_internal(
VkPhysicalDevice physical_device, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) override;
#endif
};
} /* namespace headless */

View file

@ -24,6 +24,7 @@
#include "surface_properties.hpp"
#include "layer/private_data.hpp"
#include "wsi/extensions/present_timing.hpp"
namespace wsi
{
@ -127,4 +128,28 @@ void get_surface_capabilities_common(VkPhysicalDevice physical_device, VkSurface
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
}
#if VULKAN_WSI_LAYER_EXPERIMENTAL
/**
* @brief Get the present timing surface capabilities for the specific VkSurface type.
*/
VkResult surface_properties::get_present_timing_surface_caps(
VkPhysicalDevice physical_device, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps)
{
TRY_LOG_CALL(get_present_timing_surface_caps_internal(physical_device, present_timing_surface_caps));
auto present_timing_supported = wsi::present_timing_dependencies_supported(physical_device);
if (std::holds_alternative<VkResult>(present_timing_supported))
{
return std::get<VkResult>(present_timing_supported);
}
if (!std::get<bool>(present_timing_supported))
{
present_timing_surface_caps->presentTimingSupported = VK_FALSE;
}
return VK_SUCCESS;
}
#endif /* VULKAN_WSI_LAYER_EXPERIMENTAL */
} /* namespace wsi */

View file

@ -119,9 +119,9 @@ public:
/**
* @brief Get the present timing surface capabilities for the specific VkSurface type.
*/
virtual VkResult get_present_timing_surface_caps(
VkPhysicalDevice physical_device, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) = 0;
#endif
VkResult get_present_timing_surface_caps(VkPhysicalDevice physical_device,
VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps);
#endif /* VULKAN_WSI_LAYER_EXPERIMENTAL */
/**
* @brief Virtual destructor.
@ -133,6 +133,14 @@ private:
* @brief Set which presentation modes are compatible with each other for a particular surface
*/
virtual void populate_present_mode_compatibilities() = 0;
#if VULKAN_WSI_LAYER_EXPERIMENTAL
/**
* @brief Get the present timing surface capabilities for the specific VkSurface type.
*/
virtual VkResult get_present_timing_surface_caps_internal(
VkPhysicalDevice physical_device, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) = 0;
#endif /* VULKAN_WSI_LAYER_EXPERIMENTAL */
};
class surface_format_properties

View file

@ -455,7 +455,7 @@ bool surface_properties::is_compatible_present_modes(VkPresentModeKHR present_mo
}
#if VULKAN_WSI_LAYER_EXPERIMENTAL
VkResult surface_properties::get_present_timing_surface_caps(
VkResult surface_properties::get_present_timing_surface_caps_internal(
VkPhysicalDevice physical_device, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps)
{
present_timing_surface_caps->presentTimingSupported = VK_TRUE;

View file

@ -75,10 +75,6 @@ public:
bool is_compatible_present_modes(VkPresentModeKHR present_mode_a, VkPresentModeKHR present_mode_b) override;
#if VULKAN_WSI_LAYER_EXPERIMENTAL
VkResult get_present_timing_surface_caps(
VkPhysicalDevice physical_device, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) override;
#endif
private:
surface_properties();
@ -98,6 +94,11 @@ private:
void populate_present_mode_compatibilities() override;
void get_surface_present_scaling_and_gravity(VkSurfacePresentScalingCapabilitiesEXT *scaling_capabilities) override;
#if VULKAN_WSI_LAYER_EXPERIMENTAL
VkResult get_present_timing_surface_caps_internal(
VkPhysicalDevice physical_device, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) override;
#endif
};
} // namespace wayland