| /* |
| * Copyright (c) 2025-2026 The Khronos Group Inc. |
| * Copyright (c) 2025-2026 Valve Corporation |
| * Copyright (c) 2025-2026 LunarG, Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| */ |
| // stype-check off |
| #include <vulkan/vulkan_core.h> |
| #include <string> |
| #include "binding.h" |
| #include "generated/vk_function_pointers.h" |
| #include "layer_validation_tests.h" |
| |
| void LegacyTest::CreateRenderPass() { |
| vkt::Image image(*m_device, 8, 8, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| |
| VkAttachmentReference attachment_ref = {0, VK_IMAGE_LAYOUT_GENERAL}; |
| VkSubpassDescription subpass = {}; |
| subpass.colorAttachmentCount = 1; |
| subpass.pColorAttachments = &attachment_ref; |
| |
| VkAttachmentDescription attach_desc = {}; |
| attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM; |
| attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| VkRenderPassCreateInfo rp_ci = vku::InitStructHelper(); |
| rp_ci.subpassCount = 1; |
| rp_ci.pSubpasses = &subpass; |
| rp_ci.attachmentCount = 1; |
| rp_ci.pAttachments = &attach_desc; |
| |
| vkt::RenderPass rp(*m_device, rp_ci); |
| } |
| |
| class PositiveLegacy : public LegacyTest {}; |
| |
| TEST_F(PositiveLegacy, SettingExplicitOff) { |
| TEST_DESCRIPTION("Turn off setting explicitly"); |
| const VkLayerSettingEXT layer_setting = {OBJECT_LAYER_NAME, "legacy_detection", VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1, &kVkFalse}; |
| VkLayerSettingsCreateInfoEXT layer_setting_ci = {VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT, nullptr, 1, &layer_setting}; |
| |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitFramework(&layer_setting_ci)); |
| RETURN_IF_SKIP(InitState()); |
| m_errorMonitor->ExpectSuccess(kErrorBit | kWarningBit); |
| CreateRenderPass(); |
| } |
| |
| TEST_F(PositiveLegacy, SettingDefault) { |
| TEST_DESCRIPTION("Make sure default settings have no warning"); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| m_errorMonitor->ExpectSuccess(kErrorBit | kWarningBit); |
| CreateRenderPass(); |
| } |
| |
| TEST_F(PositiveLegacy, MuteMultipleWarnings) { |
| const char* ids[] = {"WARNING-legacy-gpdp2", "WARNING-legacy-renderpass2", "WARNING-legacy-dynamicrendering"}; |
| VkLayerSettingEXT layer_settings[3] = {{OBJECT_LAYER_NAME, "legacy_detection", VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1, &kVkTrue}, |
| {OBJECT_LAYER_NAME, "message_id_filter", VK_LAYER_SETTING_TYPE_STRING_EXT, 3, ids}}; |
| VkLayerSettingsCreateInfoEXT layer_setting_ci = {VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT, nullptr, 2, layer_settings}; |
| |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_LOCAL_READ_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitFramework(&layer_setting_ci)); |
| RETURN_IF_SKIP(InitState()); |
| m_errorMonitor->ExpectSuccess(kErrorBit | kWarningBit); |
| |
| VkSubpassDescription subpass = {}; |
| subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| VkRenderPassCreateInfo rp_ci = vku::InitStructHelper(); |
| rp_ci.subpassCount = 1u; |
| rp_ci.pSubpasses = &subpass; |
| |
| // ignores WARNING-legacy-renderpass2 |
| vkt::RenderPass render_pass(*m_device, rp_ci); |
| |
| // ignores WARNING-legacy-dynamicrendering |
| vkt::Framebuffer framebuffer(*m_device, render_pass, 0, nullptr); |
| } |
| |
| TEST_F(PositiveLegacy, GetPhysicalDeviceProperties2Extension) { |
| TEST_DESCRIPTION("Show Instance extensions currently only detected if enabled, not if supported"); |
| const char* mode = "ONLY_ENABLED"; |
| VkLayerSettingEXT layer_setting[2] = {{OBJECT_LAYER_NAME, "legacy_detection", VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1, &kVkTrue}, |
| {OBJECT_LAYER_NAME, "legacy_detection_mode", VK_LAYER_SETTING_TYPE_STRING_EXT, 1, &mode}}; |
| static VkLayerSettingsCreateInfoEXT layer_setting_ci = {VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT, nullptr, 2, |
| layer_setting}; |
| RETURN_IF_SKIP(InitFramework(&layer_setting_ci)); |
| m_errorMonitor->ExpectSuccess(kErrorBit | kWarningBit); |
| |
| VkPhysicalDeviceFeatures features{}; |
| vk::GetPhysicalDeviceFeatures(Gpu(), &features); |
| |
| VkFormatProperties format_properties{}; |
| vk::GetPhysicalDeviceFormatProperties(Gpu(), VK_FORMAT_R8G8B8A8_UNORM, &format_properties); |
| } |
| |
| TEST_F(PositiveLegacy, DescriptorHeapOnlySupported) { |
| const char* mode = "ONLY_SUPPORTED"; |
| VkLayerSettingEXT layer_setting[2] = {{OBJECT_LAYER_NAME, "legacy_detection", VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1, &kVkTrue}, |
| {OBJECT_LAYER_NAME, "legacy_detection_mode", VK_LAYER_SETTING_TYPE_STRING_EXT, 1, &mode}}; |
| static VkLayerSettingsCreateInfoEXT layer_setting_ci = {VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT, nullptr, 2, |
| layer_setting}; |
| RETURN_IF_SKIP(InitFramework(&layer_setting_ci)); |
| RETURN_IF_SKIP(InitState()); |
| if (DeviceExtensionSupported(VK_EXT_DESCRIPTOR_HEAP_EXTENSION_NAME)) { |
| GTEST_SKIP() << VK_EXT_DESCRIPTOR_HEAP_EXTENSION_NAME << " is supported."; |
| } |
| m_errorMonitor->ExpectSuccess(kErrorBit | kWarningBit); |
| |
| VkDescriptorPoolSize ds_type_count = {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1}; |
| VkDescriptorPoolCreateInfo ds_pool_ci = vku::InitStructHelper(); |
| ds_pool_ci.maxSets = 1; |
| ds_pool_ci.poolSizeCount = 1; |
| ds_pool_ci.pPoolSizes = &ds_type_count; |
| vkt::DescriptorPool(*m_device, ds_pool_ci); |
| } |
| |
| TEST_F(PositiveLegacy, DescriptorHeapOnlyEnabled) { |
| const char* mode = "ONLY_ENABLED"; |
| VkLayerSettingEXT layer_setting[2] = {{OBJECT_LAYER_NAME, "legacy_detection", VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1, &kVkTrue}, |
| {OBJECT_LAYER_NAME, "legacy_detection_mode", VK_LAYER_SETTING_TYPE_STRING_EXT, 1, &mode}}; |
| static VkLayerSettingsCreateInfoEXT layer_setting_ci = {VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT, nullptr, 2, |
| layer_setting}; |
| RETURN_IF_SKIP(InitFramework(&layer_setting_ci)); |
| RETURN_IF_SKIP(InitState()); |
| if (!DeviceExtensionSupported(VK_EXT_DESCRIPTOR_HEAP_EXTENSION_NAME)) { |
| GTEST_SKIP() << VK_EXT_DESCRIPTOR_HEAP_EXTENSION_NAME << " is not supported."; |
| } |
| m_errorMonitor->ExpectSuccess(kErrorBit | kWarningBit); |
| |
| VkDescriptorPoolSize ds_type_count = {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1}; |
| VkDescriptorPoolCreateInfo ds_pool_ci = vku::InitStructHelper(); |
| ds_pool_ci.maxSets = 1; |
| ds_pool_ci.poolSizeCount = 1; |
| ds_pool_ci.pPoolSizes = &ds_type_count; |
| vkt::DescriptorPool(*m_device, ds_pool_ci); |
| } |
| |
| TEST_F(PositiveLegacy, UseDeprecatedDeviceExtensionsPromoted) { |
| // We need to explicitly allow promoted extensions to be enabled as this test relies on this behavior |
| AllowPromotedExtensions(); |
| |
| AddRequiredExtensions(VK_EXT_DEVICE_FAULT_EXTENSION_NAME); |
| const char* ids[] = {"WARNING-legacy-gpdp2"}; |
| const char* mode = "ONLY_SUPPORTED"; |
| VkLayerSettingEXT layer_settings[3] = {{OBJECT_LAYER_NAME, "legacy_detection", VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1, &kVkTrue}, |
| {OBJECT_LAYER_NAME, "legacy_detection_mode", VK_LAYER_SETTING_TYPE_STRING_EXT, 1, &mode}, |
| {OBJECT_LAYER_NAME, "message_id_filter", VK_LAYER_SETTING_TYPE_STRING_EXT, 1, ids}}; |
| VkLayerSettingsCreateInfoEXT layer_setting_ci = {VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT, nullptr, 3, layer_settings}; |
| RETURN_IF_SKIP(InitFramework(&layer_setting_ci)); |
| RETURN_IF_SKIP(InitState()); |
| m_errorMonitor->ExpectSuccess(kErrorBit | kWarningBit); |
| |
| if (DeviceExtensionSupported(VK_KHR_DEVICE_FAULT_EXTENSION_NAME)) { |
| GTEST_SKIP() << VK_KHR_DEVICE_FAULT_EXTENSION_NAME << " is supported."; |
| } |
| |
| VkDevice local_device; |
| VkDeviceCreateInfo dev_info = vku::InitStructHelper(); |
| VkDeviceQueueCreateInfo queue_info = vku::InitStructHelper(); |
| queue_info.queueFamilyIndex = 0; |
| queue_info.queueCount = 1; |
| float qp = 1; |
| queue_info.pQueuePriorities = &qp; |
| dev_info.queueCreateInfoCount = 1; |
| dev_info.pQueueCreateInfos = &queue_info; |
| dev_info.enabledLayerCount = 0; |
| dev_info.ppEnabledLayerNames = nullptr; |
| dev_info.enabledExtensionCount = m_device_extension_names.size(); |
| dev_info.ppEnabledExtensionNames = m_device_extension_names.data(); |
| |
| vk::CreateDevice(this->Gpu(), &dev_info, nullptr, &local_device); |
| vk::DestroyDevice(local_device, nullptr); |
| } |