Skip to content

Commit db53dbe

Browse files
DaKvasNVspencer-lunarg
authored andcommitted
layers: Update VUID 09246 for Present Timing
Allow Present Timing Calibration to request multiple present stages
1 parent bf39330 commit db53dbe

3 files changed

Lines changed: 176 additions & 6 deletions

File tree

layers/core_checks/cc_device.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,8 @@ bool core::Instance::ValidateDeviceQueueCreateInfos(const vvl::PhysicalDevice &p
232232
const VkQueueFamilyProperties requested_queue_family_props = pd_state.queue_family_properties[requested_queue_family];
233233

234234
// if using protected flag, make sure queue supports it
235-
if ((flags & VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT) && ((requested_queue_family_props.queueFlags & VK_QUEUE_PROTECTED_BIT) == 0)) {
235+
if ((flags & VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT) &&
236+
((requested_queue_family_props.queueFlags & VK_QUEUE_PROTECTED_BIT) == 0)) {
236237
skip |= LogError("VUID-VkDeviceQueueCreateInfo-flags-06449", pd_state.Handle(), info_loc.dot(Field::queueFamilyIndex),
237238
"(%" PRIu32 ") does not have VK_QUEUE_PROTECTED_BIT supported, but pQueueCreateInfos[%" PRIu32
238239
"].flags has VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT.",
@@ -697,11 +698,19 @@ bool CoreChecks::PreCallValidateGetCalibratedTimestampsKHR(VkDevice device, uint
697698
std::vector<VkTimeDomainKHR> valid_time_domains(count);
698699
query_function(physical_device, &count, valid_time_domains.data());
699700

700-
vvl::unordered_map<VkTimeDomainKHR, uint32_t> time_domain_map;
701+
vvl::unordered_map<VkTimeDomainKHR, VkPresentStageFlagsEXT> time_domain_map;
701702
for (uint32_t i = 0; i < timestampCount; i++) {
702703
const VkTimeDomainKHR time_domain = pTimestampInfos[i].timeDomain;
704+
705+
// The VK_TIME_DOMAIN_PRESENT_STAGE_LOCAL_EXT domain can be duplicated if the present stage is different
706+
const auto *present_stage_info =
707+
vku::FindStructInPNextChain<VkSwapchainCalibratedTimestampInfoEXT>(pTimestampInfos[i].pNext);
708+
const VkPresentStageFlagsEXT present_stage = (time_domain == VK_TIME_DOMAIN_PRESENT_STAGE_LOCAL_EXT && present_stage_info)
709+
? present_stage_info->presentStage
710+
: vvl::kU32Max;
711+
703712
auto it = time_domain_map.find(time_domain);
704-
if (it != time_domain_map.end()) {
713+
if (it != time_domain_map.end() && (it->second & present_stage) != 0) {
705714
skip |= LogError("VUID-vkGetCalibratedTimestampsKHR-timeDomain-09246", device,
706715
error_obj.location.dot(Field::pTimestampInfos, i).dot(Field::timeDomain),
707716
"and pTimestampInfos[%" PRIu32 "].timeDomain are both %s.", it->second,
@@ -712,7 +721,7 @@ bool CoreChecks::PreCallValidateGetCalibratedTimestampsKHR(VkDevice device, uint
712721
error_obj.location.dot(Field::pTimestampInfos, i).dot(Field::timeDomain), "is %s.",
713722
string_VkTimeDomainKHR(time_domain));
714723
}
715-
time_domain_map[time_domain] = i;
724+
time_domain_map[time_domain] |= present_stage;
716725
}
717726
return skip;
718727
}
@@ -814,7 +823,6 @@ bool CoreChecks::PreCallValidateCreatePipelineBinariesKHR(VkDevice device, const
814823
const VkAllocationCallbacks *pAllocator,
815824
VkPipelineBinaryHandlesInfoKHR *pBinaries,
816825
const ErrorObject &error_obj) const {
817-
818826
bool skip = false;
819827

820828
uint32_t pointerCount = 0;

tests/unit/wsi.cpp

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5725,7 +5725,8 @@ TEST_F(NegativeWsi, PresentTimingsCalibrateableTimeDomains2) {
57255725

57265726
VkSwapchainCalibratedTimestampInfoEXT swapchain_timestamp_info = vku::InitStructHelper();
57275727
swapchain_timestamp_info.swapchain = swapchain;
5728-
swapchain_timestamp_info.presentStage = VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT | VK_PRESENT_STAGE_REQUEST_DEQUEUED_BIT_EXT;
5728+
swapchain_timestamp_info.presentStage =
5729+
VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT | VK_PRESENT_STAGE_REQUEST_DEQUEUED_BIT_EXT;
57295730

57305731
VkCalibratedTimestampInfoKHR timestamp_info = vku::InitStructHelper(&swapchain_timestamp_info);
57315732
timestamp_info.timeDomain = VK_TIME_DOMAIN_PRESENT_STAGE_LOCAL_EXT;
@@ -5736,6 +5737,71 @@ TEST_F(NegativeWsi, PresentTimingsCalibrateableTimeDomains2) {
57365737
m_errorMonitor->VerifyFound();
57375738
}
57385739

5740+
TEST_F(NegativeWsi, PresentTimingsCalibrateableTimeDomains3) {
5741+
SetTargetApiVersion(VK_API_VERSION_1_1);
5742+
AddSurfaceExtension();
5743+
AddRequiredExtensions(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
5744+
AddRequiredExtensions(VK_KHR_CALIBRATED_TIMESTAMPS_EXTENSION_NAME);
5745+
AddRequiredExtensions(VK_EXT_PRESENT_TIMING_EXTENSION_NAME);
5746+
AddRequiredFeature(vkt::Feature::presentTiming);
5747+
RETURN_IF_SKIP(Init());
5748+
RETURN_IF_SKIP(InitSurface());
5749+
InitSwapchainInfo();
5750+
5751+
VkSwapchainCreateInfoKHR swapchain_ci = vku::InitStructHelper();
5752+
swapchain_ci.flags = VK_SWAPCHAIN_CREATE_PRESENT_TIMING_BIT_EXT;
5753+
swapchain_ci.surface = m_surface;
5754+
swapchain_ci.minImageCount = m_surface_capabilities.minImageCount;
5755+
swapchain_ci.imageFormat = m_surface_formats[0].format;
5756+
swapchain_ci.imageColorSpace = m_surface_formats[0].colorSpace;
5757+
swapchain_ci.imageExtent = m_surface_capabilities.minImageExtent;
5758+
swapchain_ci.imageArrayLayers = 1;
5759+
swapchain_ci.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
5760+
swapchain_ci.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
5761+
swapchain_ci.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
5762+
swapchain_ci.compositeAlpha = m_surface_composite_alpha;
5763+
swapchain_ci.presentMode = m_surface_non_shared_present_mode;
5764+
swapchain_ci.clipped = VK_FALSE;
5765+
swapchain_ci.oldSwapchain = 0;
5766+
vkt::Swapchain swapchain(*m_device, swapchain_ci);
5767+
5768+
uint32_t time_domain_count = 0u;
5769+
vk::GetPhysicalDeviceCalibrateableTimeDomainsKHR(gpu_, &time_domain_count, nullptr);
5770+
std::vector<VkTimeDomainKHR> time_domains(time_domain_count);
5771+
vk::GetPhysicalDeviceCalibrateableTimeDomainsKHR(Gpu(), &time_domain_count, time_domains.data());
5772+
5773+
bool found = false;
5774+
for (uint32_t i = 0; i < time_domain_count; ++i) {
5775+
if (time_domains[i] == VK_TIME_DOMAIN_PRESENT_STAGE_LOCAL_EXT) {
5776+
found = true;
5777+
break;
5778+
}
5779+
}
5780+
if (!found) {
5781+
GTEST_SKIP() << "VK_TIME_DOMAIN_PRESENT_STAGE_LOCAL_EXT not supported";
5782+
}
5783+
5784+
std::array<VkPresentStageFlagBitsEXT, 3> present_stages_to_test{VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT,
5785+
VK_PRESENT_STAGE_REQUEST_DEQUEUED_BIT_EXT,
5786+
VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT};
5787+
std::vector<VkSwapchainCalibratedTimestampInfoEXT> swapchain_timestamp_infos(present_stages_to_test.size());
5788+
std::vector<VkCalibratedTimestampInfoKHR> timestamp_infos(swapchain_timestamp_infos.size());
5789+
for (size_t i = 0; i < swapchain_timestamp_infos.size(); i++) {
5790+
swapchain_timestamp_infos[i] = vku::InitStructHelper();
5791+
swapchain_timestamp_infos[i].swapchain = swapchain;
5792+
swapchain_timestamp_infos[i].presentStage = present_stages_to_test[i];
5793+
5794+
timestamp_infos[i] = vku::InitStructHelper(&swapchain_timestamp_infos[i]);
5795+
timestamp_infos[i].timeDomain = VK_TIME_DOMAIN_PRESENT_STAGE_LOCAL_EXT;
5796+
}
5797+
5798+
std::vector<uint64_t> timestamps(timestamp_infos.size());
5799+
uint64_t max_deviation;
5800+
m_errorMonitor->SetDesiredError("VUID-vkGetCalibratedTimestampsKHR-timeDomain-09246");
5801+
vk::GetCalibratedTimestampsKHR(device(), timestamp_infos.size(), timestamp_infos.data(), timestamps.data(), &max_deviation);
5802+
m_errorMonitor->VerifyFound();
5803+
}
5804+
57395805
TEST_F(NegativeWsi, PresentTimingsOutOfOrder) {
57405806
SetTargetApiVersion(VK_API_VERSION_1_1);
57415807
AddSurfaceExtension();

tests/unit/wsi_positive.cpp

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3038,6 +3038,102 @@ TEST_F(PositiveWsi, PresentTimings) {
30383038
}
30393039
}
30403040

3041+
TEST_F(PositiveWsi, PresentTimingsCalibrateableTimeDomains) {
3042+
SetTargetApiVersion(VK_API_VERSION_1_1);
3043+
AddSurfaceExtension();
3044+
AddRequiredExtensions(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
3045+
AddRequiredExtensions(VK_KHR_CALIBRATED_TIMESTAMPS_EXTENSION_NAME);
3046+
AddRequiredExtensions(VK_EXT_PRESENT_TIMING_EXTENSION_NAME);
3047+
AddRequiredFeature(vkt::Feature::presentTiming);
3048+
RETURN_IF_SKIP(Init());
3049+
RETURN_IF_SKIP(InitSurface());
3050+
InitSwapchainInfo();
3051+
3052+
if (IsPlatformMockICD()) {
3053+
GTEST_SKIP() << "Skipping on mock icd because time domains cannot be queried.";
3054+
}
3055+
3056+
VkSurfaceCapabilities2KHR capabilities2 = vku::InitStructHelper();
3057+
VkPhysicalDeviceSurfaceInfo2KHR surface_info = vku::InitStructHelper();
3058+
surface_info.surface = m_surface;
3059+
vk::GetPhysicalDeviceSurfaceCapabilities2KHR(gpu_, &surface_info, &capabilities2);
3060+
3061+
VkPresentTimingSurfaceCapabilitiesEXT present_timing_surface_capabilities = vku::InitStructHelper();
3062+
VkSurfaceCapabilities2KHR surface_capabilities = vku::InitStructHelper(&present_timing_surface_capabilities);
3063+
vk::GetPhysicalDeviceSurfaceCapabilities2KHR(gpu_, &surface_info, &surface_capabilities);
3064+
3065+
uint32_t present_mode_count = 0;
3066+
vk::GetPhysicalDeviceSurfacePresentModesKHR(gpu_, m_surface, &present_mode_count, nullptr);
3067+
if (present_mode_count == 0) {
3068+
GTEST_SKIP() << "No present modes supported";
3069+
}
3070+
3071+
std::vector<VkPresentModeKHR> present_modes(present_mode_count);
3072+
vk::GetPhysicalDeviceSurfacePresentModesKHR(gpu_, m_surface, &present_mode_count, present_modes.data());
3073+
3074+
VkSwapchainCreateInfoKHR swapchain_ci = vku::InitStructHelper();
3075+
swapchain_ci.flags = VK_SWAPCHAIN_CREATE_PRESENT_TIMING_BIT_EXT | VK_SWAPCHAIN_CREATE_PRESENT_ID_2_BIT_KHR;
3076+
swapchain_ci.surface = m_surface;
3077+
swapchain_ci.minImageCount = m_surface_capabilities.minImageCount;
3078+
swapchain_ci.imageFormat = m_surface_formats[0].format;
3079+
swapchain_ci.imageColorSpace = m_surface_formats[0].colorSpace;
3080+
swapchain_ci.imageExtent = m_surface_capabilities.minImageExtent;
3081+
swapchain_ci.imageArrayLayers = 1;
3082+
swapchain_ci.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3083+
swapchain_ci.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
3084+
swapchain_ci.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
3085+
swapchain_ci.compositeAlpha = m_surface_composite_alpha;
3086+
swapchain_ci.presentMode = present_modes[0];
3087+
swapchain_ci.clipped = VK_FALSE;
3088+
swapchain_ci.oldSwapchain = 0;
3089+
vkt::Swapchain swapchain(*m_device, swapchain_ci);
3090+
3091+
uint32_t time_domain_count = 0u;
3092+
vk::GetPhysicalDeviceCalibrateableTimeDomainsKHR(gpu_, &time_domain_count, nullptr);
3093+
std::vector<VkTimeDomainKHR> time_domains(time_domain_count);
3094+
vk::GetPhysicalDeviceCalibrateableTimeDomainsKHR(Gpu(), &time_domain_count, time_domains.data());
3095+
3096+
VkTimeDomainKHR non_present_stage_time_domain = VK_TIME_DOMAIN_MAX_ENUM_KHR;
3097+
bool found = false;
3098+
for (uint32_t i = 0; i < time_domain_count; ++i) {
3099+
if (time_domains[i] == VK_TIME_DOMAIN_PRESENT_STAGE_LOCAL_EXT) {
3100+
found = true;
3101+
break;
3102+
} else {
3103+
non_present_stage_time_domain = time_domains[i];
3104+
}
3105+
}
3106+
if (!found) {
3107+
GTEST_SKIP() << "VK_TIME_DOMAIN_PRESENT_STAGE_LOCAL_EXT not supported";
3108+
}
3109+
3110+
std::vector<VkPresentStageFlagsEXT> present_stages_to_test{VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT,
3111+
VK_PRESENT_STAGE_REQUEST_DEQUEUED_BIT_EXT};
3112+
if (non_present_stage_time_domain != VK_TIME_DOMAIN_MAX_ENUM_KHR) {
3113+
present_stages_to_test.push_back(0);
3114+
}
3115+
3116+
std::vector<VkSwapchainCalibratedTimestampInfoEXT> swapchain_timestamp_infos(present_stages_to_test.size());
3117+
std::vector<VkCalibratedTimestampInfoKHR> timestamp_infos(present_stages_to_test.size());
3118+
for (size_t i = 0; i < present_stages_to_test.size(); i++) {
3119+
swapchain_timestamp_infos[i] = vku::InitStructHelper();
3120+
swapchain_timestamp_infos[i].swapchain = swapchain;
3121+
swapchain_timestamp_infos[i].presentStage = present_stages_to_test[i];
3122+
3123+
timestamp_infos[i] = vku::InitStructHelper(&swapchain_timestamp_infos[i]);
3124+
timestamp_infos[i].timeDomain =
3125+
present_stages_to_test[i] ? VK_TIME_DOMAIN_PRESENT_STAGE_LOCAL_EXT : non_present_stage_time_domain;
3126+
}
3127+
3128+
// Disable this error for now; the spec incorrectly labelled this VUIDs as implicit, when in-fact it
3129+
// only applies when VkSwapchainCalibratedTimestampInfoEXT::presentStage is VK_TIME_DOMAIN_PRESENT_STAGE_LOCAL_EXT
3130+
m_errorMonitor->SetAllowedFailureMsg("VUID-VkSwapchainCalibratedTimestampInfoEXT-presentStage-requiredbitmask");
3131+
3132+
std::vector<uint64_t> timestamps(present_stages_to_test.size());
3133+
uint64_t max_deviation{};
3134+
vk::GetCalibratedTimestampsKHR(device(), timestamp_infos.size(), timestamp_infos.data(), timestamps.data(), &max_deviation);
3135+
}
3136+
30413137
TEST_F(PositiveWsi, PresentTimingsFull) {
30423138
SetTargetApiVersion(VK_API_VERSION_1_1);
30433139
AddSurfaceExtension();

0 commit comments

Comments
 (0)