/* Copyright (c) 2015-2026 The Khronos Group Inc.
 * Copyright (c) 2015-2026 Valve Corporation
 * Copyright (c) 2015-2026 LunarG, Inc.
 * Copyright (C) 2015-2026 Google 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
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "generated/vk_extension_helper.h"
#include "stateless/stateless_validation.h"
#include "generated/enum_flag_bits.h"
#include "generated/dispatch_functions.h"
#include "containers/container_utils.h"

namespace stateless {
// Traits objects to allow string_join to operate on collections of const char *
template <typename String>
struct StringJoinSizeTrait {
    static size_t size(const String &str) { return str.size(); }
};

template <>
struct StringJoinSizeTrait<const char *> {
    static size_t size(const char *str) {
        if (!str) return 0;
        return strlen(str);
    }
};
// Similar to perl/python join
//    * String must support size, reserve, append, and be default constructable
//    * StringCollection must support size, const forward iteration, and store
//      strings compatible with String::append
//    * Accessor trait can be set if default accessors (compatible with string
//      and const char *) don't support size(StringCollection::value_type &)
//
// Return type based on sep type
template <typename String = std::string, typename StringCollection = std::vector<String>,
          typename Accessor = StringJoinSizeTrait<typename StringCollection::value_type>>
static inline String string_join(const String &sep, const StringCollection &strings) {
    String joined;
    const size_t count = strings.size();
    if (!count) return joined;

    // Prereserved storage, s.t. we will execute in linear time (avoids reallocation copies)
    size_t reserve = (count - 1) * sep.size();
    for (const auto &str : strings) {
        reserve += Accessor::size(str);  // abstracted to allow const char * type in StringCollection
    }
    joined.reserve(reserve + 1);

    // Seps only occur *between* strings entries, so first is special
    auto current = strings.cbegin();
    joined.append(*current);
    ++current;
    for (; current != strings.cend(); ++current) {
        joined.append(sep);
        joined.append(*current);
    }
    return joined;
}

// Requires StringCollection::value_type has a const char * constructor and is compatible the string_join::String above
template <typename StringCollection = std::vector<std::string>, typename SepString = std::string>
static inline SepString string_join(const char *sep, const StringCollection &strings) {
    return string_join<SepString, StringCollection>(SepString(sep), strings);
}

template <typename ExtensionState>
bool Instance::ValidateExtensionReqs(const ExtensionState &extensions, const char *vuid, const char *extension_type,
                                     vvl::Extension extension, const Location &extension_loc) const {
    bool skip = false;
    if (extension == vvl::Extension::Empty) {
        return skip;
    }
    auto info = extensions.GetInfo(extension);

    if (!info.state) {
        return skip;  // Unknown extensions cannot be checked so report OK
    }

    // Check against the required list in the info
    std::vector<const char *> missing;
    for (const auto &req : info.requirements) {
        if (!IsExtEnabled(extensions.*(req.enabled))) {
            missing.push_back(req.name);
        }
    }

    // Report any missing requirements
    if (missing.size()) {
        std::string missing_joined_list = string_join(", ", missing);
        skip |= LogError(vuid, instance, extension_loc, "Missing extension%s required by the %s extension %s: %s.",
                         ((missing.size() > 1) ? "s" : ""), extension_type, String(extension), missing_joined_list.c_str());
    }
    return skip;
}

ExtEnabled ExtensionStateByName(const DeviceExtensions &extensions, vvl::Extension extension) {
    auto info = extensions.GetInfo(extension);
    // unknown extensions can't be enabled in extension struct
    ExtEnabled state = info.state ? extensions.*(info.state) : kNotSupported;
    return state;
}

bool Instance::PreCallValidateCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
                                             VkInstance *pInstance, const ErrorObject &error_obj) const {
    bool skip = false;
    Location loc = error_obj.location;
    // Note: From the spec--
    //  Providing a NULL VkInstanceCreateInfo::pApplicationInfo or providing an apiVersion of 0 is equivalent to providing
    //  an apiVersion of VK_MAKE_VERSION(1, 0, 0).  (a.k.a. VK_API_VERSION_1_0)
    uint32_t local_api_version = (pCreateInfo->pApplicationInfo ? pCreateInfo->pApplicationInfo->apiVersion : VK_API_VERSION_1_0);
    // Create and use a local instance extension object, as an actual instance has not been created yet
    InstanceExtensions instance_extensions(local_api_version, pCreateInfo);
    DeviceExtensions device_extensions(instance_extensions, local_api_version);
    Context context(*this, error_obj, device_extensions);

    skip |= context.ValidateStructType(loc.dot(Field::pCreateInfo), pCreateInfo, VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, true,
                                       "VUID-vkCreateInstance-pCreateInfo-parameter", "VUID-VkInstanceCreateInfo-sType-sType");

    if (pAllocator != nullptr) {
        [[maybe_unused]] const Location pAllocator_loc = loc.dot(Field::pAllocator);
        skip |= context.ValidateAllocationCallbacks(*pAllocator, pAllocator_loc);
    }
    skip |= context.ValidateRequiredPointer(loc.dot(Field::pInstance), pInstance, "VUID-vkCreateInstance-pInstance-parameter");

    uint32_t api_version_nopatch = VK_MAKE_VERSION(VK_VERSION_MAJOR(local_api_version), VK_VERSION_MINOR(local_api_version), 0);
    const Location create_info_loc = loc.dot(Field::pCreateInfo);
    if (api_version != api_version_nopatch) {
        if ((api_version_nopatch < VK_API_VERSION_1_0) && (local_api_version != 0)) {
            skip |= LogError("VUID-VkApplicationInfo-apiVersion-04010", instance,
                             create_info_loc.dot(Field::pApplicationInfo).dot(Field::apiVersion),
                             "is (0x%08x). "
                             "Using VK_API_VERSION_%" PRIu32 "_%" PRIu32 ".",
                             local_api_version, api_version.Major(), api_version.Minor());
        } else {
            skip |= LogWarning(kVUIDUndefined, instance, create_info_loc.dot(Field::pApplicationInfo).dot(Field::apiVersion),
                               "is (0x%08x). "
                               "Assuming VK_API_VERSION_%" PRIu32 "_%" PRIu32 ".",
                               local_api_version, api_version.Major(), api_version.Minor());
        }
    }

    if (pCreateInfo != nullptr) {
        skip |= context.ValidateFlags(create_info_loc.dot(Field::flags), vvl::FlagBitmask::VkInstanceCreateFlagBits,
                                      AllVkInstanceCreateFlagBits, pCreateInfo->flags, kOptionalFlags,
                                      "VUID-VkInstanceCreateInfo-flags-parameter");

        skip |= context.ValidateStructType(
            create_info_loc.dot(Field::pApplicationInfo), pCreateInfo->pApplicationInfo, VK_STRUCTURE_TYPE_APPLICATION_INFO, false,
            "VUID-VkInstanceCreateInfo-pApplicationInfo-parameter", "VUID-VkApplicationInfo-sType-sType");

        if (pCreateInfo->pApplicationInfo != nullptr) {
            [[maybe_unused]] const Location pApplicationInfo_loc = create_info_loc.dot(Field::pApplicationInfo);
            skip |= context.ValidateStructPnext(pApplicationInfo_loc, pCreateInfo->pApplicationInfo->pNext, 0, nullptr,
                                                GeneratedVulkanHeaderVersion, "VUID-VkApplicationInfo-pNext-pNext", kVUIDUndefined,
                                                true);
        }

        skip |= context.ValidateStringArray(create_info_loc.dot(Field::enabledLayerCount),
                                            create_info_loc.dot(Field::ppEnabledLayerNames), pCreateInfo->enabledLayerCount,
                                            pCreateInfo->ppEnabledLayerNames, false, true, kVUIDUndefined,
                                            "VUID-VkInstanceCreateInfo-ppEnabledLayerNames-parameter");

        skip |= context.ValidateStringArray(create_info_loc.dot(Field::enabledExtensionCount),
                                            create_info_loc.dot(Field::ppEnabledExtensionNames), pCreateInfo->enabledExtensionCount,
                                            pCreateInfo->ppEnabledExtensionNames, false, true, kVUIDUndefined,
                                            "VUID-VkInstanceCreateInfo-ppEnabledExtensionNames-parameter");
    }

    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
        vvl::Extension extension = GetExtension(pCreateInfo->ppEnabledExtensionNames[i]);
        skip |= ValidateExtensionReqs(instance_extensions, "VUID-vkCreateInstance-ppEnabledExtensionNames-01388", "instance",
                                      extension, create_info_loc.dot(Field::ppEnabledExtensionNames, i));
    }
    if (pCreateInfo->flags & VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR &&
        !instance_extensions.vk_khr_portability_enumeration) {
        skip |= LogError("VUID-VkInstanceCreateInfo-flags-06559", instance, create_info_loc.dot(Field::flags),
                         "has VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR set, but "
                         "ppEnabledExtensionNames does not include VK_KHR_portability_enumeration");
    }

#ifdef VK_USE_PLATFORM_METAL_EXT
    auto export_metal_object_info = vku::FindStructInPNextChain<VkExportMetalObjectCreateInfoEXT>(pCreateInfo->pNext);
    while (export_metal_object_info) {
        if ((export_metal_object_info->exportObjectType != VK_EXPORT_METAL_OBJECT_TYPE_METAL_DEVICE_BIT_EXT) &&
            (export_metal_object_info->exportObjectType != VK_EXPORT_METAL_OBJECT_TYPE_METAL_COMMAND_QUEUE_BIT_EXT)) {
            skip |= LogError("VUID-VkInstanceCreateInfo-pNext-06779", instance, error_obj.location,
                             "The pNext chain contains a VkExportMetalObjectCreateInfoEXT whose "
                             "exportObjectType = %s, but only VkExportMetalObjectCreateInfoEXT structs with exportObjectType of "
                             "VK_EXPORT_METAL_OBJECT_TYPE_METAL_DEVICE_BIT_EXT or "
                             "VK_EXPORT_METAL_OBJECT_TYPE_METAL_COMMAND_QUEUE_BIT_EXT are allowed",
                             string_VkExportMetalObjectTypeFlagBitsEXT(export_metal_object_info->exportObjectType));
        }
        export_metal_object_info = vku::FindStructInPNextChain<VkExportMetalObjectCreateInfoEXT>(export_metal_object_info->pNext);
    }
#endif  // VK_USE_PLATFORM_METAL_EXT

    // avoid redundant pNext-pNext errors from the cases where we have specific VUs by returning early
    const auto *debug_report_callback = vku::FindStructInPNextChain<VkDebugReportCallbackCreateInfoEXT>(pCreateInfo->pNext);
    if (debug_report_callback && !instance_extensions.vk_ext_debug_report) {
        skip |=
            LogError("VUID-VkInstanceCreateInfo-pNext-04925", instance, create_info_loc.dot(Field::ppEnabledExtensionNames),
                     "does not include VK_EXT_debug_report, but the pNext chain includes VkDebugReportCallbackCreateInfoEXT.\n%s",
                     PrintPNextChain(Struct::VkInstanceCreateInfo, pCreateInfo->pNext).c_str());
        return skip;
    }
    const auto *debug_utils_messenger = vku::FindStructInPNextChain<VkDebugUtilsMessengerCreateInfoEXT>(pCreateInfo->pNext);
    if (debug_utils_messenger && !instance_extensions.vk_ext_debug_utils) {
        skip |=
            LogError("VUID-VkInstanceCreateInfo-pNext-04926", instance, create_info_loc.dot(Field::ppEnabledExtensionNames),
                     "does not include VK_EXT_debug_utils, but the pNext chain includes VkDebugUtilsMessengerCreateInfoEXT.\n%s",
                     PrintPNextChain(Struct::VkInstanceCreateInfo, pCreateInfo->pNext).c_str());
        return skip;
    }
    const auto *direct_driver_loading_list = vku::FindStructInPNextChain<VkDirectDriverLoadingListLUNARG>(pCreateInfo->pNext);
    if (direct_driver_loading_list && !instance_extensions.vk_lunarg_direct_driver_loading) {
        skip |= LogError(
            "VUID-VkInstanceCreateInfo-pNext-09400", instance, create_info_loc.dot(Field::ppEnabledExtensionNames),
            "does not include VK_LUNARG_direct_driver_loading, but the pNext chain includes VkDirectDriverLoadingListLUNARG.\n%s",
            PrintPNextChain(Struct::VkInstanceCreateInfo, pCreateInfo->pNext).c_str());
        return skip;
    }

    if (const auto *validation_features = vku::FindStructInPNextChain<VkValidationFeaturesEXT>(pCreateInfo->pNext)) {
        bool debug_printf = false;
        bool gpu_assisted = false;
        bool reserve_slot = false;
        for (uint32_t i = 0; i < validation_features->enabledValidationFeatureCount; i++) {
            switch (validation_features->pEnabledValidationFeatures[i]) {
                case VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT:
                    gpu_assisted = true;
                    break;

                case VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT:
                    debug_printf = true;
                    break;

                case VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT:
                    reserve_slot = true;
                    break;

                default:
                    break;
            }
        }
        if (reserve_slot && !gpu_assisted && !debug_printf) {
            skip |= LogError("VUID-VkValidationFeaturesEXT-pEnabledValidationFeatures-02967", instance,
                             create_info_loc.pNext(Struct::VkValidationFeaturesEXT, Field::pEnabledValidationFeatures),
                             "includes VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT but no "
                             "VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT or VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT.");
        }
    }

    constexpr std::array allowed_structs_VkInstanceCreateInfo = {VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,
                                                                 VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
                                                                 VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_LIST_LUNARG,
                                                                 VK_STRUCTURE_TYPE_EXPORT_METAL_OBJECT_CREATE_INFO_EXT,
                                                                 VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT,
                                                                 VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT,
                                                                 VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT};

    skip |= context.ValidateStructPnext(create_info_loc, pCreateInfo->pNext, allowed_structs_VkInstanceCreateInfo.size(),
                                        allowed_structs_VkInstanceCreateInfo.data(), GeneratedVulkanHeaderVersion,
                                        "VUID-VkInstanceCreateInfo-pNext-pNext", "VUID-VkInstanceCreateInfo-sType-unique", true);

    return skip;
}

void Instance::CommonPostCallRecordEnumeratePhysicalDevice(const VkPhysicalDevice *phys_devices, const int count) {
    // Assume phys_devices is valid
    assert(phys_devices);
    for (int i = 0; i < count; ++i) {
        const auto &phys_device = phys_devices[i];
        if (0 == physical_device_properties_map.count(phys_device)) {
            auto phys_dev_props = new VkPhysicalDeviceProperties;
            DispatchGetPhysicalDeviceProperties(phys_device, phys_dev_props);
            physical_device_properties_map[phys_device] = phys_dev_props;

            // Enumerate the Device Ext Properties to save the PhysicalDevice supported extension state
            uint32_t ext_count = 0;

            std::vector<VkExtensionProperties> ext_props{};
            DispatchEnumerateDeviceExtensionProperties(phys_device, nullptr, &ext_count, nullptr);
            ext_props.resize(ext_count);
            DispatchEnumerateDeviceExtensionProperties(phys_device, nullptr, &ext_count, ext_props.data());

            DeviceExtensions phys_dev_exts(extensions, api_version, ext_props);
            physical_device_extensions[phys_device] = std::move(phys_dev_exts);
        }
    }
}

void Instance::PostCallRecordEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
                                                      VkPhysicalDevice *pPhysicalDevices, const RecordObject &record_obj) {
    if ((VK_SUCCESS != record_obj.result) && (VK_INCOMPLETE != record_obj.result)) {
        return;
    }

    if (pPhysicalDeviceCount && pPhysicalDevices) {
        CommonPostCallRecordEnumeratePhysicalDevice(pPhysicalDevices, *pPhysicalDeviceCount);
    }
}

void Instance::PostCallRecordEnumeratePhysicalDeviceGroups(VkInstance instance, uint32_t *pPhysicalDeviceGroupCount,
                                                           VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties,
                                                           const RecordObject &record_obj) {
    if ((VK_SUCCESS != record_obj.result) && (VK_INCOMPLETE != record_obj.result)) {
        return;
    }

    if (pPhysicalDeviceGroupCount && pPhysicalDeviceGroupProperties) {
        for (uint32_t i = 0; i < *pPhysicalDeviceGroupCount; i++) {
            const auto &group = pPhysicalDeviceGroupProperties[i];
            CommonPostCallRecordEnumeratePhysicalDevice(group.physicalDevices, group.physicalDeviceCount);
        }
    }
}

void Instance::PreCallRecordDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator,
                                            const RecordObject &record_obj) {
    for (auto it = physical_device_properties_map.begin(); it != physical_device_properties_map.end();) {
        delete (it->second);
        it = physical_device_properties_map.erase(it);
    }
}

void Device::FinishDeviceSetup(const VkDeviceCreateInfo *pCreateInfo, const Location &loc) {
    std::vector<VkExtensionProperties> ext_props{};
    uint32_t ext_count = 0;
    DispatchEnumerateDeviceExtensionProperties(physical_device, nullptr, &ext_count, nullptr);
    ext_props.resize(ext_count);
    DispatchEnumerateDeviceExtensionProperties(physical_device, nullptr, &ext_count, ext_props.data());
    for (const auto &prop : ext_props) {
        vvl::Extension extension = GetExtension(prop.extensionName);
        if (extension == vvl::Extension::_VK_EXT_discard_rectangles) {
            discard_rectangles_extension_version = prop.specVersion;
        } else if (extension == vvl::Extension::_VK_NV_scissor_exclusive) {
            scissor_exclusive_extension_version = prop.specVersion;
        }
    }

    has_zero_queues = pCreateInfo->queueCreateInfoCount == 0;
}

bool Instance::manual_PreCallValidateCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
                                                  const VkAllocationCallbacks *pAllocator, VkDevice *pDevice,
                                                  const Context &context) const {
    bool skip = false;
    const auto &error_obj = context.error_obj;

    const Location create_info_loc = error_obj.location.dot(Field::pCreateInfo);
    // VU was removed in 1.4.344
    // https://gitlab.khronos.org/vulkan/vulkan/-/issues/4725
    skip |= context.ValidateStringArray(create_info_loc.dot(Field::enabledLayerCount),
                                            create_info_loc.dot(Field::ppEnabledLayerNames), pCreateInfo->enabledLayerCount,
                                            pCreateInfo->ppEnabledLayerNames, false, true, kVUIDUndefined,
                                            "VUID-VkDeviceCreateInfo-ppEnabledLayerNames-parameter");
    if (pCreateInfo->ppEnabledLayerNames) {
        for (size_t i = 0; i < pCreateInfo->enabledLayerCount; i++) {
            skip |=
                context.ValidateString(create_info_loc.dot(Field::ppEnabledLayerNames),
                                    "VUID-VkDeviceCreateInfo-ppEnabledLayerNames-parameter", pCreateInfo->ppEnabledLayerNames[i]);
        }
    }

    // If this device supports VK_KHR_portability_subset, it must be enabled
    const auto &exposed_extensions = physical_device_extensions.at(physicalDevice);
    const bool portability_supported = exposed_extensions.vk_khr_portability_subset;
    bool portability_requested = false;
    bool fragmentmask_requested = false;

    vvl::unordered_set<vvl::Extension> enabled_extensions{};
    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
        vvl::Extension extension = GetExtension(pCreateInfo->ppEnabledExtensionNames[i]);
        enabled_extensions.insert(extension);
        skip |= context.ValidateString(create_info_loc.dot(Field::ppEnabledExtensionNames),
                                       "VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-parameter",
                                       pCreateInfo->ppEnabledExtensionNames[i]);
        skip |= ValidateExtensionReqs(extensions, "VUID-vkCreateDevice-ppEnabledExtensionNames-01387", "device", extension,
                                      create_info_loc.dot(Field::ppEnabledExtensionNames, i));
        if (extension == vvl::Extension::_VK_KHR_portability_subset) {
            portability_requested = true;
        }
        if (extension == vvl::Extension::_VK_AMD_shader_fragment_mask) {
            fragmentmask_requested = true;
        }
    }

    if (portability_supported && !portability_requested) {
        skip |= LogError("VUID-VkDeviceCreateInfo-pProperties-04451", physicalDevice, error_obj.location,
                         "VK_KHR_portability_subset must be enabled because physical device %s supports it",
                         FormatHandle(physicalDevice).c_str());
    }

    if (IsExtEnabledByCreateinfo(ExtensionStateByName(extensions, vvl::Extension::_VK_AMD_negative_viewport_height))) {
        const bool maint1 = IsExtEnabledByCreateinfo(ExtensionStateByName(extensions, vvl::Extension::_VK_KHR_maintenance1));
        // Only need to check for VK_KHR_MAINTENANCE_1_EXTENSION_NAME if api version is 1.0, otherwise it's deprecated due to
        // integration into api version 1.1
        if (api_version >= VK_API_VERSION_1_1) {
            skip |= LogError("VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-01840", physicalDevice,
                             create_info_loc.dot(Field::ppEnabledExtensionNames),
                             "must not include "
                             "VK_AMD_negative_viewport_height if api version is greater than or equal to 1.1.");
        } else if (maint1) {
            skip |= LogError("VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-00374", physicalDevice,
                             create_info_loc.dot(Field::ppEnabledExtensionNames),
                             "must not simultaneously include "
                             "VK_KHR_maintenance1 and VK_AMD_negative_viewport_height.");
        }
    }

    if (fragmentmask_requested) {
        const auto *descriptor_buffer_features = vku::FindStructInPNextChain<VkPhysicalDeviceDescriptorBufferFeaturesEXT>(pCreateInfo->pNext);
        if (descriptor_buffer_features && descriptor_buffer_features->descriptorBuffer) {
            skip |=
                LogError("VUID-VkDeviceCreateInfo-None-08095", physicalDevice, create_info_loc.dot(Field::ppEnabledExtensionNames),
                         "must not contain VK_AMD_shader_fragment_mask if the descriptorBuffer feature is enabled.");
        }
    }

    {
        const bool khr_bda =
            IsExtEnabledByCreateinfo(ExtensionStateByName(extensions, vvl::Extension::_VK_KHR_buffer_device_address));
        const bool ext_bda =
            IsExtEnabledByCreateinfo(ExtensionStateByName(extensions, vvl::Extension::_VK_EXT_buffer_device_address));
        if (khr_bda && ext_bda) {
            skip |= LogError("VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-03328", physicalDevice,
                             create_info_loc.dot(Field::ppEnabledExtensionNames),
                             "must not contain both VK_KHR_buffer_device_address and "
                             "VK_EXT_buffer_device_address.");
        }
    }

    const auto features2 = vku::FindStructInPNextChain<VkPhysicalDeviceFeatures2>(pCreateInfo->pNext);
    if (pCreateInfo->pNext != nullptr && pCreateInfo->pEnabledFeatures && features2) {
        // Cannot include VkPhysicalDeviceFeatures2 and have non-null pEnabledFeatures
        skip |= LogError("VUID-VkDeviceCreateInfo-pNext-00373", physicalDevice, create_info_loc.dot(Field::pNext),
                         "includes a VkPhysicalDeviceFeatures2 struct when pCreateInfo->pEnabledFeatures is not NULL.\n%s",
                         PrintPNextChain(Struct::VkDeviceCreateInfo, pCreateInfo->pNext).c_str());
    }

    const VkPhysicalDeviceFeatures *features = features2 ? &features2->features : pCreateInfo->pEnabledFeatures;

    if (const auto *robustness2_features =
            vku::FindStructInPNextChain<VkPhysicalDeviceRobustness2FeaturesKHR>(pCreateInfo->pNext)) {
        if (features && robustness2_features->robustBufferAccess2 && !features->robustBufferAccess) {
            skip |= LogError("VUID-VkPhysicalDeviceRobustness2FeaturesKHR-robustBufferAccess2-04000", physicalDevice,
                             error_obj.location, "If robustBufferAccess2 is enabled then robustBufferAccess must be enabled.");
        }
    }

    if (const auto *raytracing_features =
            vku::FindStructInPNextChain<VkPhysicalDeviceRayTracingPipelineFeaturesKHR>(pCreateInfo->pNext)) {
        if (raytracing_features->rayTracingPipelineShaderGroupHandleCaptureReplayMixed &&
            !raytracing_features->rayTracingPipelineShaderGroupHandleCaptureReplay) {
            skip |= LogError(
                "VUID-VkPhysicalDeviceRayTracingPipelineFeaturesKHR-rayTracingPipelineShaderGroupHandleCaptureReplayMixed-03575",
                physicalDevice, error_obj.location,
                "If rayTracingPipelineShaderGroupHandleCaptureReplayMixed is VK_TRUE, "
                "rayTracingPipelineShaderGroupHandleCaptureReplay "
                "must also be VK_TRUE.");
        }
    }

    // might be set in Feature12 struct
    bool any_update_after_bind_feature = false;
    if (const auto *di_features = vku::FindStructInPNextChain<VkPhysicalDeviceDescriptorIndexingFeatures>(pCreateInfo->pNext)) {
        any_update_after_bind_feature = di_features->descriptorBindingUniformBufferUpdateAfterBind ||
                                        di_features->descriptorBindingStorageBufferUpdateAfterBind ||
                                        di_features->descriptorBindingUniformTexelBufferUpdateAfterBind ||
                                        di_features->descriptorBindingStorageTexelBufferUpdateAfterBind;
    }

    const auto *vulkan_11_features = vku::FindStructInPNextChain<VkPhysicalDeviceVulkan11Features>(pCreateInfo->pNext);
    if (vulkan_11_features) {
        const VkBaseOutStructure *current = reinterpret_cast<const VkBaseOutStructure *>(pCreateInfo->pNext);
        constexpr std::array illegal_feature_structs_with_11 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES,
                                                                VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES,
                                                                VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES,
                                                                VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,
                                                                VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES,
                                                                VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES};
        while (current) {
            if (IsValueIn(current->sType, illegal_feature_structs_with_11)) {
                skip |= LogError("VUID-VkDeviceCreateInfo-pNext-02829", physicalDevice, error_obj.location,
                                 "If the pNext chain includes a VkPhysicalDeviceVulkan11Features structure, then "
                                 "it must not include a %s structure. The features in %s were promoted in Vulkan 1.1 and is also "
                                 "found in VkPhysicalDeviceVulkan11Features. To prevent one feature setting something to VK_TRUE "
                                 "and the other to VK_FALSE, only one struct containing the feature is allowed.\n%s",
                                 string_VkStructureName(current->sType), string_VkStructureName(current->sType),
                                 PrintPNextChain(Struct::VkDeviceCreateInfo, pCreateInfo->pNext).c_str());
                break;
            }
            current = reinterpret_cast<const VkBaseOutStructure *>(current->pNext);
        }

        // Check features are enabled if matching extension is passed in as well
        if (vulkan_11_features->shaderDrawParameters == VK_FALSE &&
            enabled_extensions.find(vvl::Extension::_VK_KHR_shader_draw_parameters) != enabled_extensions.end()) {
            skip |= LogError("VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-04476", physicalDevice, error_obj.location,
                             "%s is enabled but VkPhysicalDeviceVulkan11Features::shaderDrawParameters is not VK_TRUE.",
                             VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME);
        }
    }

    const auto *vulkan_12_features = vku::FindStructInPNextChain<VkPhysicalDeviceVulkan12Features>(pCreateInfo->pNext);
    if (vulkan_12_features) {
        const VkBaseOutStructure *current = reinterpret_cast<const VkBaseOutStructure *>(pCreateInfo->pNext);
        constexpr std::array illegal_feature_structs_with_12 = {
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES};
        while (current) {
            if (IsValueIn(current->sType, illegal_feature_structs_with_12)) {
                skip |= LogError("VUID-VkDeviceCreateInfo-pNext-02830", physicalDevice, create_info_loc.dot(Field::pNext),
                                 "chain includes a VkPhysicalDeviceVulkan12Features structure, then it must not "
                                 "include a %s structure. The features in %s were promoted in Vulkan 1.2 and is also found in "
                                 "VkPhysicalDeviceVulkan12Features. To prevent one feature setting something to VK_TRUE and the "
                                 "other to VK_FALSE, only one struct containing the feature is allowed.\n%s",
                                 string_VkStructureName(current->sType), string_VkStructureName(current->sType),
                                 PrintPNextChain(Struct::VkDeviceCreateInfo, pCreateInfo->pNext).c_str());
                break;
            }
            current = reinterpret_cast<const VkBaseOutStructure *>(current->pNext);
        }
        // Check features are enabled if matching extension is passed in as well
        if (vulkan_12_features->drawIndirectCount == VK_FALSE &&
            enabled_extensions.find(vvl::Extension::_VK_KHR_draw_indirect_count) != enabled_extensions.end()) {
            skip |= LogError("VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-02831", physicalDevice, error_obj.location,
                             "%s is enabled but VkPhysicalDeviceVulkan12Features::drawIndirectCount is not VK_TRUE.",
                             VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
        }
        if (vulkan_12_features->samplerMirrorClampToEdge == VK_FALSE &&
            enabled_extensions.find(vvl::Extension::_VK_KHR_sampler_mirror_clamp_to_edge) != enabled_extensions.end()) {
            skip |= LogError("VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-02832", physicalDevice, error_obj.location,
                             " %s is enabled but VkPhysicalDeviceVulkan12Features::samplerMirrorClampToEdge "
                             "is not VK_TRUE.",
                             VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME);
        }
        if (vulkan_12_features->descriptorIndexing == VK_FALSE &&
            enabled_extensions.find(vvl::Extension::_VK_EXT_descriptor_indexing) != enabled_extensions.end()) {
            skip |= LogError("VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-02833", physicalDevice, error_obj.location,
                             "%s is enabled but VkPhysicalDeviceVulkan12Features::descriptorIndexing is not VK_TRUE.",
                             VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
        }
        if (vulkan_12_features->samplerFilterMinmax == VK_FALSE &&
            enabled_extensions.find(vvl::Extension::_VK_EXT_sampler_filter_minmax) != enabled_extensions.end()) {
            skip |= LogError("VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-02834", physicalDevice, error_obj.location,
                             "%s is enabled but VkPhysicalDeviceVulkan12Features::samplerFilterMinmax is not VK_TRUE.",
                             VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME);
        }

        if ((vulkan_12_features->shaderOutputViewportIndex == VK_FALSE || vulkan_12_features->shaderOutputLayer == VK_FALSE) &&
            enabled_extensions.find(vvl::Extension::_VK_EXT_shader_viewport_index_layer) != enabled_extensions.end()) {
            skip |= LogError("VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-02835", physicalDevice, error_obj.location,
                             "%s is enabled but both VkPhysicalDeviceVulkan12Features::shaderOutputViewportIndex "
                             "and VkPhysicalDeviceVulkan12Features::shaderOutputLayer are not VK_TRUE.",
                             VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME);
        }

        if (vulkan_12_features->bufferDeviceAddress == VK_TRUE) {
            if (IsExtEnabledByCreateinfo(ExtensionStateByName(extensions, vvl::Extension::_VK_EXT_buffer_device_address))) {
                skip |= LogError("VUID-VkDeviceCreateInfo-pNext-04748", physicalDevice, create_info_loc.dot(Field::pNext),
                                 "chain includes VkPhysicalDeviceVulkan12Features with bufferDeviceAddress "
                                 "set to VK_TRUE and ppEnabledExtensionNames contains VK_EXT_buffer_device_address");
            }
        }

        any_update_after_bind_feature = vulkan_12_features->descriptorBindingUniformBufferUpdateAfterBind ||
                                        vulkan_12_features->descriptorBindingStorageBufferUpdateAfterBind ||
                                        vulkan_12_features->descriptorBindingUniformTexelBufferUpdateAfterBind ||
                                        vulkan_12_features->descriptorBindingStorageTexelBufferUpdateAfterBind;
    }

    const auto *vulkan_13_features = vku::FindStructInPNextChain<VkPhysicalDeviceVulkan13Features>(pCreateInfo->pNext);
    if (vulkan_13_features) {
        const VkBaseOutStructure *current = reinterpret_cast<const VkBaseOutStructure *>(pCreateInfo->pNext);
        constexpr std::array illegal_feature_structs_with_13 = {
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES};
        while (current) {
            if (IsValueIn(current->sType, illegal_feature_structs_with_13)) {
                skip |= LogError("VUID-VkDeviceCreateInfo-pNext-06532", physicalDevice, create_info_loc.dot(Field::pNext),
                                 "chain includes a VkPhysicalDeviceVulkan13Features structure, then it must not "
                                 "include a %s structure. The features in %s were promoted in Vulkan 1.3 and is also found in "
                                 "VkPhysicalDeviceVulkan13Features. To prevent one feature setting something to VK_TRUE and the "
                                 "other to VK_FALSE, only one struct containing the feature is allowed.\n%s",
                                 string_VkStructureName(current->sType), string_VkStructureName(current->sType),
                                 PrintPNextChain(Struct::VkDeviceCreateInfo, pCreateInfo->pNext).c_str());
                break;
            }
            current = reinterpret_cast<const VkBaseOutStructure *>(current->pNext);
        }
    }

    // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/8969
    const auto *vulkan_14_features = vku::FindStructInPNextChain<VkPhysicalDeviceVulkan14Features>(pCreateInfo->pNext);
    if (vulkan_14_features) {
        const VkBaseOutStructure *current = reinterpret_cast<const VkBaseOutStructure *>(pCreateInfo->pNext);
        constexpr std::array illegal_feature_structs_with_14 = {
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_ROTATE_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT_CONTROLS_2_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EXPECT_ASSUME_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_LOCAL_READ_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_6_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES,
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES};
        while (current) {
            if (IsValueIn(current->sType, illegal_feature_structs_with_14)) {
                skip |= LogError("VUID-VkDeviceCreateInfo-pNext-10360", physicalDevice, create_info_loc.dot(Field::pNext),
                                 "chain includes a VkPhysicalDeviceVulkan14Features structure, then it must not "
                                 "include a %s structure. The features in %s were promoted in Vulkan 1.4 and is also found in "
                                 "VkPhysicalDeviceVulkan14Features. To prevent one feature setting something to VK_TRUE and the "
                                 "other to VK_FALSE, only one struct containing the feature is allowed.\n%s",
                                 string_VkStructureName(current->sType), string_VkStructureName(current->sType),
                                 PrintPNextChain(Struct::VkDeviceCreateInfo, pCreateInfo->pNext).c_str());
                break;
            }
            current = reinterpret_cast<const VkBaseOutStructure *>(current->pNext);
        }
        if (vulkan_14_features->pushDescriptor == VK_FALSE &&
            enabled_extensions.find(vvl::Extension::_VK_KHR_push_descriptor) != enabled_extensions.end()) {
            skip |= LogError("VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-10858", physicalDevice, error_obj.location,
                             "%s is enabled but VkPhysicalDeviceVulkan14Features::pushDescriptor is not VK_TRUE.",
                             VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
        }
    }

    // Validate pCreateInfo->pQueueCreateInfos
    if (pCreateInfo->pQueueCreateInfos) {
        for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; ++i) {
            const VkDeviceQueueCreateInfo &queue_create_info = pCreateInfo->pQueueCreateInfos[i];
            const uint32_t requested_queue_family = queue_create_info.queueFamilyIndex;
            if (requested_queue_family == VK_QUEUE_FAMILY_IGNORED) {
                skip |= LogError("VUID-VkDeviceQueueCreateInfo-queueFamilyIndex-00381", physicalDevice,
                                 create_info_loc.dot(Field::pQueueCreateInfos, i).dot(Field::queueFamilyIndex),
                                 "is VK_QUEUE_FAMILY_IGNORED, but it is required to provide a valid queue family index value.");
            }

            if (queue_create_info.pQueuePriorities != nullptr) {
                for (uint32_t j = 0; j < queue_create_info.queueCount; ++j) {
                    const float queue_priority = queue_create_info.pQueuePriorities[j];
                    if (!(queue_priority >= 0.f) || !(queue_priority <= 1.f)) {
                        skip |= LogError("VUID-VkDeviceQueueCreateInfo-pQueuePriorities-00383", physicalDevice,
                                         create_info_loc.dot(Field::pQueueCreateInfos, i).dot(Field::pQueuePriorities, j),
                                         "(%f) is not between 0 and 1 (inclusive).", queue_priority);
                    }
                }
            }

            // Need to know if protectedMemory feature is passed in preCall to creating the device
            VkBool32 protected_memory = VK_FALSE;
            const auto *protected_features =
                vku::FindStructInPNextChain<VkPhysicalDeviceProtectedMemoryFeatures>(pCreateInfo->pNext);
            if (protected_features) {
                protected_memory = protected_features->protectedMemory;
            } else if (vulkan_11_features) {
                protected_memory = vulkan_11_features->protectedMemory;
            }
            if (((queue_create_info.flags & VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT) != 0) && (protected_memory == VK_FALSE)) {
                skip |= LogError(
                    "VUID-VkDeviceQueueCreateInfo-flags-02861", physicalDevice, create_info_loc.dot(Field::flags),
                    "includes VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT, but the protectedMemory feature is not being enabled.");
            }
        }
    }

    // feature dependencies for VK_KHR_variable_pointers
    {
        const auto *variable_pointers_features =
            vku::FindStructInPNextChain<VkPhysicalDeviceVariablePointersFeatures>(pCreateInfo->pNext);
        VkBool32 variable_pointers = VK_FALSE;
        VkBool32 variable_pointers_storage_buffer = VK_FALSE;
        if (vulkan_11_features) {
            variable_pointers = vulkan_11_features->variablePointers;
            variable_pointers_storage_buffer = vulkan_11_features->variablePointersStorageBuffer;
        } else if (variable_pointers_features) {
            variable_pointers = variable_pointers_features->variablePointers;
            variable_pointers_storage_buffer = variable_pointers_features->variablePointersStorageBuffer;
        }
        if ((variable_pointers == VK_TRUE) && (variable_pointers_storage_buffer == VK_FALSE)) {
            skip |=
                LogError("VUID-VkPhysicalDeviceVariablePointersFeatures-variablePointers-01431", physicalDevice, error_obj.location,
                         "If variablePointers is VK_TRUE then variablePointersStorageBuffer also needs to be VK_TRUE");
        }
    }

    // feature dependencies for VK_KHR_multiview
    {
        const auto *multiview_features = vku::FindStructInPNextChain<VkPhysicalDeviceMultiviewFeatures>(pCreateInfo->pNext);
        VkBool32 multiview = VK_FALSE;
        VkBool32 multiview_geometry_shader = VK_FALSE;
        VkBool32 multiview_tessellation_shader = VK_FALSE;
        if (vulkan_11_features) {
            multiview = vulkan_11_features->multiview;
            multiview_geometry_shader = vulkan_11_features->multiviewGeometryShader;
            multiview_tessellation_shader = vulkan_11_features->multiviewTessellationShader;
        } else if (multiview_features) {
            multiview = multiview_features->multiview;
            multiview_geometry_shader = multiview_features->multiviewGeometryShader;
            multiview_tessellation_shader = multiview_features->multiviewTessellationShader;
        }
        if ((multiview == VK_FALSE) && (multiview_geometry_shader == VK_TRUE)) {
            skip |= LogError("VUID-VkPhysicalDeviceMultiviewFeatures-multiviewGeometryShader-00580", physicalDevice,
                             error_obj.location, "If multiviewGeometryShader is VK_TRUE then multiview also needs to be VK_TRUE");
        }
        if ((multiview == VK_FALSE) && (multiview_tessellation_shader == VK_TRUE)) {
            skip |=
                LogError("VUID-VkPhysicalDeviceMultiviewFeatures-multiviewTessellationShader-00581", physicalDevice,
                         error_obj.location, "If multiviewTessellationShader is VK_TRUE then multiview also needs to be VK_TRUE");
        }

        const auto *fsr_features = vku::FindStructInPNextChain<VkPhysicalDeviceFragmentShadingRateFeaturesKHR>(pCreateInfo->pNext);
        const auto *mesh_shader_features = vku::FindStructInPNextChain<VkPhysicalDeviceMeshShaderFeaturesEXT>(pCreateInfo->pNext);
        if (mesh_shader_features) {
            if ((multiview == VK_FALSE) && (mesh_shader_features->multiviewMeshShader)) {
                skip |= LogError("VUID-VkPhysicalDeviceMeshShaderFeaturesEXT-multiviewMeshShader-07032", physicalDevice,
                                 error_obj.location, "If multiviewMeshShader is VK_TRUE then multiview also needs to be VK_TRUE");
            }
            if ((!fsr_features || !fsr_features->primitiveFragmentShadingRate) &&
                (mesh_shader_features->primitiveFragmentShadingRateMeshShader)) {
                skip |= LogError("VUID-VkPhysicalDeviceMeshShaderFeaturesEXT-primitiveFragmentShadingRateMeshShader-07033",
                                 physicalDevice, error_obj.location,
                                 "If primitiveFragmentShadingRateMeshShader is VK_TRUE then primitiveFragmentShadingRate also "
                                 "needs to be VK_TRUE");
            }
        }
    }

    if (features && features->robustBufferAccess && any_update_after_bind_feature) {
        VkPhysicalDeviceDescriptorIndexingProperties di_props = vku::InitStructHelper();
        VkPhysicalDeviceProperties2 props2 = vku::InitStructHelper(&di_props);
        DispatchGetPhysicalDeviceProperties2Helper(api_version, physicalDevice, &props2);
        if (!di_props.robustBufferAccessUpdateAfterBind) {
            skip |= LogError("VUID-VkDeviceCreateInfo-robustBufferAccess-10247", physicalDevice, error_obj.location,
                             "robustBufferAccessUpdateAfterBind is false, but both robustBufferAccess and a "
                             "descriptorBinding*UpdateAfterBind feature are enabled.");
        }
    }

    if (const auto *fragment_shading_rate_features =
            vku::FindStructInPNextChain<VkPhysicalDeviceFragmentShadingRateFeaturesKHR>(pCreateInfo->pNext)) {
        const VkPhysicalDeviceShadingRateImageFeaturesNV *shading_rate_image_features =
            vku::FindStructInPNextChain<VkPhysicalDeviceShadingRateImageFeaturesNV>(pCreateInfo->pNext);

        if (shading_rate_image_features && shading_rate_image_features->shadingRateImage) {
            if (fragment_shading_rate_features->pipelineFragmentShadingRate) {
                skip |= LogError("VUID-VkDeviceCreateInfo-shadingRateImage-04478", physicalDevice, error_obj.location,
                                 "Cannot enable shadingRateImage and pipelineFragmentShadingRate features simultaneously.");
            }
            if (fragment_shading_rate_features->primitiveFragmentShadingRate) {
                skip |= LogError("VUID-VkDeviceCreateInfo-shadingRateImage-04479", physicalDevice, error_obj.location,
                                 "Cannot enable shadingRateImage and primitiveFragmentShadingRate features simultaneously.");
            }
            if (fragment_shading_rate_features->attachmentFragmentShadingRate) {
                skip |= LogError("VUID-VkDeviceCreateInfo-shadingRateImage-04480", physicalDevice, error_obj.location,
                                 "Cannot enable shadingRateImage and attachmentFragmentShadingRate features "
                                 "simultaneously.");
            }
        }

        const VkPhysicalDeviceFragmentDensityMapFeaturesEXT *fragment_density_map_features =
            vku::FindStructInPNextChain<VkPhysicalDeviceFragmentDensityMapFeaturesEXT>(pCreateInfo->pNext);

        if (fragment_density_map_features && fragment_density_map_features->fragmentDensityMap) {
            if (fragment_shading_rate_features->pipelineFragmentShadingRate) {
                skip |= LogError("VUID-VkDeviceCreateInfo-fragmentDensityMap-04481", physicalDevice, error_obj.location,
                                 "Cannot enable fragmentDensityMap and pipelineFragmentShadingRate features "
                                 "simultaneously.");
            }
            if (fragment_shading_rate_features->primitiveFragmentShadingRate) {
                skip |= LogError("VUID-VkDeviceCreateInfo-fragmentDensityMap-04482", physicalDevice, error_obj.location,
                                 "Cannot enable fragmentDensityMap and primitiveFragmentShadingRate features "
                                 "simultaneously.");
            }
            if (fragment_shading_rate_features->attachmentFragmentShadingRate) {
                skip |= LogError("VUID-VkDeviceCreateInfo-fragmentDensityMap-04483", physicalDevice, error_obj.location,
                                 "Cannot enable fragmentDensityMap and attachmentFragmentShadingRate features "
                                 "simultaneously.");
            }
        }
    }

    if (const auto *shader_image_atomic_int64_features =
            vku::FindStructInPNextChain<VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT>(pCreateInfo->pNext)) {
        if (shader_image_atomic_int64_features->sparseImageInt64Atomics &&
            !shader_image_atomic_int64_features->shaderImageInt64Atomics) {
            skip |= LogError("VUID-VkDeviceCreateInfo-None-04896", physicalDevice, error_obj.location,
                             "If sparseImageInt64Atomics feature is enabled then shaderImageInt64Atomics "
                             "feature must also be enabled.");
        }
    }

    if (const auto *shader_atomic_float_features =
            vku::FindStructInPNextChain<VkPhysicalDeviceShaderAtomicFloatFeaturesEXT>(pCreateInfo->pNext)) {
        if (shader_atomic_float_features->sparseImageFloat32Atomics && !shader_atomic_float_features->shaderImageFloat32Atomics) {
            skip |= LogError("VUID-VkDeviceCreateInfo-None-04897", physicalDevice, error_obj.location,
                             "If sparseImageFloat32Atomics feature is enabled then shaderImageFloat32Atomics "
                             "feature must also be enabled.");
        }
        if (shader_atomic_float_features->sparseImageFloat32AtomicAdd &&
            !shader_atomic_float_features->shaderImageFloat32AtomicAdd) {
            skip |= LogError("VUID-VkDeviceCreateInfo-None-04898", physicalDevice, error_obj.location,
                             "If sparseImageFloat32AtomicAdd feature is enabled then shaderImageFloat32AtomicAdd "
                             "feature must also be enabled.");
        }
    }

    if (const auto *shader_atomic_float2_features =
            vku::FindStructInPNextChain<VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT>(pCreateInfo->pNext)) {
        if (shader_atomic_float2_features->sparseImageFloat32AtomicMinMax &&
            !shader_atomic_float2_features->shaderImageFloat32AtomicMinMax) {
            skip |= LogError("VUID-VkDeviceCreateInfo-sparseImageFloat32AtomicMinMax-04975", physicalDevice, error_obj.location,
                             "If sparseImageFloat32AtomicMinMax feature is enabled then shaderImageFloat32AtomicMinMax "
                             "feature must also be enabled.");
        }
    }

    if (const auto *device_group_ci = vku::FindStructInPNextChain<VkDeviceGroupDeviceCreateInfo>(pCreateInfo->pNext)) {
        for (uint32_t i = 0; i < device_group_ci->physicalDeviceCount - 1; ++i) {
            for (uint32_t j = i + 1; j < device_group_ci->physicalDeviceCount; ++j) {
                if (device_group_ci->pPhysicalDevices[i] == device_group_ci->pPhysicalDevices[j]) {
                    skip |=
                        LogError("VUID-VkDeviceGroupDeviceCreateInfo-pPhysicalDevices-00375", physicalDevice, error_obj.location,
                                 "VkDeviceGroupDeviceCreateInfo has a duplicated physical device "
                                 "in pPhysicalDevices [%" PRIu32 "] and [%" PRIu32 "].",
                                 i, j);
                }
            }
        }
    }

    const auto *cache_control = vku::FindStructInPNextChain<VkDevicePipelineBinaryInternalCacheControlKHR>(pCreateInfo->pNext);
    if (cache_control && cache_control->disableInternalCache) {
        VkPhysicalDevicePipelineBinaryPropertiesKHR pipeline_binary_props = vku::InitStructHelper();
        VkPhysicalDeviceProperties2 props2 = vku::InitStructHelper(&pipeline_binary_props);
        DispatchGetPhysicalDeviceProperties2Helper(api_version, physicalDevice, &props2);

        if (!pipeline_binary_props.pipelineBinaryInternalCacheControl) {
            skip |= LogError("VUID-VkDevicePipelineBinaryInternalCacheControlKHR-disableInternalCache-09602", physicalDevice,
                             error_obj.location,
                             "If disableInternalCache is VK_TRUE then pipelineBinaryInternalCacheControl must also be VK_TRUE");
        }
    }
    return skip;
}

bool Instance::manual_PreCallValidateGetPhysicalDeviceImageFormatProperties2(
    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,
    VkImageFormatProperties2 *pImageFormatProperties, const Context &context) const {
    bool skip = false;
    const auto &error_obj = context.error_obj;

    if (pImageFormatInfo != nullptr) {
        const Location format_info_loc = error_obj.location.dot(Field::pImageFormatInfo);
        const auto image_stencil_struct = vku::FindStructInPNextChain<VkImageStencilUsageCreateInfo>(pImageFormatInfo->pNext);
        if (image_stencil_struct != nullptr) {
            if ((image_stencil_struct->stencilUsage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0) {
                VkImageUsageFlags legal_flags = (VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
                // No flags other than the legal attachment bits may be set
                legal_flags |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
                if ((image_stencil_struct->stencilUsage & ~legal_flags) != 0) {
                    skip |= LogError("VUID-VkImageStencilUsageCreateInfo-stencilUsage-02539", physicalDevice,
                                     format_info_loc.pNext(Struct::VkImageStencilUsageCreateInfo, Field::stencilUsage), "is %s.",
                                     string_VkImageUsageFlags(image_stencil_struct->stencilUsage).c_str());
                }
            }
        }
        const auto image_drm_format = vku::FindStructInPNextChain<VkPhysicalDeviceImageDrmFormatModifierInfoEXT>(pImageFormatInfo->pNext);
        if (image_drm_format) {
            if (pImageFormatInfo->tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
                skip |= LogError("VUID-VkPhysicalDeviceImageFormatInfo2-tiling-02249", physicalDevice,
                                 format_info_loc.dot(Field::tiling),
                                 "(%s) but no VkPhysicalDeviceImageDrmFormatModifierInfoEXT in pNext chain.\n%s",
                                 string_VkImageTiling(pImageFormatInfo->tiling),
                                 PrintPNextChain(Struct::VkPhysicalDeviceImageFormatInfo2, pImageFormatInfo->pNext).c_str());
            }
            if (image_drm_format->sharingMode == VK_SHARING_MODE_CONCURRENT) {
                if (image_drm_format->queueFamilyIndexCount <= 1) {
                    skip |=
                        LogError("VUID-VkPhysicalDeviceImageDrmFormatModifierInfoEXT-sharingMode-02315", physicalDevice,
                                 format_info_loc.pNext(Struct::VkPhysicalDeviceImageDrmFormatModifierInfoEXT, Field::sharingMode),
                                 "is VK_SHARING_MODE_CONCURRENT, but queueFamilyIndexCount is %" PRIu32 ".",
                                 image_drm_format->queueFamilyIndexCount);
                } else if (!image_drm_format->pQueueFamilyIndices) {
                    skip |= LogError(
                        "VUID-VkPhysicalDeviceImageDrmFormatModifierInfoEXT-sharingMode-02314", physicalDevice,
                        format_info_loc.pNext(Struct::VkPhysicalDeviceImageDrmFormatModifierInfoEXT, Field::sharingMode),
                        "is VK_SHARING_MODE_CONCURRENT, queueFamilyIndexCount is %" PRIu32 ", but pQueueFamilyIndices is NULL.",
                        image_drm_format->queueFamilyIndexCount);
                } else {
                    uint32_t queue_family_property_count = 0;
                    DispatchGetPhysicalDeviceQueueFamilyProperties2Helper(api_version, physicalDevice, &queue_family_property_count,
                                                                          nullptr);
                    vvl::unordered_set<uint32_t> queue_family_indices_set;
                    for (uint32_t i = 0; i < image_drm_format->queueFamilyIndexCount; i++) {
                        const uint32_t queue_index = image_drm_format->pQueueFamilyIndices[i];
                        if (queue_family_indices_set.find(queue_index) != queue_family_indices_set.end()) {
                            skip |= LogError("VUID-VkPhysicalDeviceImageDrmFormatModifierInfoEXT-sharingMode-02316", physicalDevice,
                                             format_info_loc.pNext(Struct::VkPhysicalDeviceImageDrmFormatModifierInfoEXT,
                                                                   Field::pQueueFamilyIndices, i),
                                             "is %" PRIu32 ", but is duplicated in pQueueFamilyIndices.", queue_index);
                            break;
                        } else if (queue_index >= queue_family_property_count) {
                            skip |= LogError(
                                "VUID-VkPhysicalDeviceImageDrmFormatModifierInfoEXT-sharingMode-02316", physicalDevice,
                                format_info_loc.pNext(Struct::VkPhysicalDeviceImageDrmFormatModifierInfoEXT,
                                                      Field::pQueueFamilyIndices, i),
                                "is %" PRIu32
                                ", but vkGetPhysicalDeviceQueueFamilyProperties2::pQueueFamilyPropertyCount returned %" PRIu32 ".",
                                queue_index, queue_family_property_count);
                        }
                        queue_family_indices_set.emplace(queue_index);
                    }
                }
            }
        } else {
            if (pImageFormatInfo->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
                skip |= LogError("VUID-VkPhysicalDeviceImageFormatInfo2-tiling-02249", physicalDevice,
                                 format_info_loc.dot(Field::tiling),
                                 "is VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, but pNext chain not include "
                                 "VkPhysicalDeviceImageDrmFormatModifierInfoEXT.\n%s",
                                 PrintPNextChain(Struct::VkPhysicalDeviceImageFormatInfo2, pImageFormatInfo->pNext).c_str());
            }
        }
        if (pImageFormatInfo->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
            (pImageFormatInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)) {
            const auto format_list = vku::FindStructInPNextChain<VkImageFormatListCreateInfo>(pImageFormatInfo->pNext);
            if (!format_list || format_list->viewFormatCount == 0) {
                skip |= LogError(
                    "VUID-VkPhysicalDeviceImageFormatInfo2-tiling-02313", physicalDevice, format_info_loc,
                    "tiling is VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT and flags contain VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT "
                    "bit, but the pNext chain does not contain an instance of VkImageFormatListCreateInfo with non-zero "
                    "viewFormatCount.");
            }
        }
    }

    return skip;
}

bool Instance::manual_PreCallValidateGetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
                                                                            VkImageType type, VkImageTiling tiling,
                                                                            VkImageUsageFlags usage, VkImageCreateFlags flags,
                                                                            VkImageFormatProperties *pImageFormatProperties,
                                                                            const Context &context) const {
    bool skip = false;
    const auto &error_obj = context.error_obj;

    if (tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
        skip |= LogError("VUID-vkGetPhysicalDeviceImageFormatProperties-tiling-02248", physicalDevice,
                         error_obj.location.dot(Field::tiling), "is VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT.");
    }

    return skip;
}

bool Device::manual_PreCallValidateSetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsObjectNameInfoEXT *pNameInfo,
                                                              const Context &context) const {
    bool skip = false;
    const auto &error_obj = context.error_obj;
    const Location name_info_loc = error_obj.location.dot(Field::pNameInfo);
    if (pNameInfo->objectType == VK_OBJECT_TYPE_UNKNOWN) {
        skip |= LogError("VUID-vkSetDebugUtilsObjectNameEXT-pNameInfo-02587", device, name_info_loc.dot(Field::objectType),
                         "cannot be VK_OBJECT_TYPE_UNKNOWN.");
    }
    if (pNameInfo->objectHandle == HandleToUint64(VK_NULL_HANDLE)) {
        skip |= LogError("VUID-vkSetDebugUtilsObjectNameEXT-pNameInfo-02588", device, name_info_loc.dot(Field::objectHandle),
                         "cannot be VK_NULL_HANDLE.");
    }

    if ((pNameInfo->objectType == VK_OBJECT_TYPE_UNKNOWN) && (pNameInfo->objectHandle == HandleToUint64(VK_NULL_HANDLE))) {
        skip |= LogError("VUID-VkDebugUtilsObjectNameInfoEXT-objectType-02589", device, name_info_loc.dot(Field::objectType),
                         "is VK_OBJECT_TYPE_UNKNOWN but objectHandle is VK_NULL_HANDLE");
    }

    return skip;
}

bool Device::manual_PreCallValidateSetDebugUtilsObjectTagEXT(VkDevice device, const VkDebugUtilsObjectTagInfoEXT *pTagInfo,
                                                             const Context &context) const {
    bool skip = false;
    const auto &error_obj = context.error_obj;
    if (pTagInfo->objectType == VK_OBJECT_TYPE_UNKNOWN) {
        skip |= LogError("VUID-VkDebugUtilsObjectTagInfoEXT-objectType-01908", device,
                         error_obj.location.dot(Field::pTagInfo).dot(Field::objectType), "cannot be VK_OBJECT_TYPE_UNKNOWN.");
    }
    return skip;
}

bool Instance::manual_PreCallValidateGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
                                                                  VkPhysicalDeviceProperties2 *pProperties,
                                                                  const Context &context) const {
    bool skip = false;
    const auto &error_obj = context.error_obj;
    const auto *api_props_lists = vku::FindStructInPNextChain<VkPhysicalDeviceLayeredApiPropertiesListKHR>(pProperties->pNext);
    if (api_props_lists && api_props_lists->pLayeredApis) {
        for (uint32_t i = 0; i < api_props_lists->layeredApiCount; i++) {
            if (const auto *api_vulkan_props = vku::FindStructInPNextChain<VkPhysicalDeviceLayeredApiVulkanPropertiesKHR>(
                    api_props_lists->pLayeredApis[i].pNext)) {
                const VkBaseOutStructure *current = static_cast<const VkBaseOutStructure *>(api_vulkan_props->properties.pNext);
                while (current) {
                    // only VkPhysicalDeviceDriverProperties and VkPhysicalDeviceIDProperties allowed
                    if (current->sType != VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES &&
                        current->sType != VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES) {
                        skip |= LogError("VUID-VkPhysicalDeviceLayeredApiVulkanPropertiesKHR-pNext-10011", physicalDevice,
                                         error_obj.location.dot(Field::pProperties)
                                             .pNext(Struct::VkPhysicalDeviceLayeredApiPropertiesListKHR, Field::pLayeredApis, i)
                                             .dot(Field::properties)
                                             .dot(Field::pNext),
                                         "contains an invalid struct (%s).", string_VkStructureType(current->sType));
                    }
                    current = current->pNext;
                }
            }
        }
    }
    return skip;
}

bool Instance::ValidateGetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format,
                                                          VkFormatProperties2 *pFormatProperties, const Context &context) const {
    bool skip = false;

    if (IsValueIn(format, {VK_FORMAT_G8_B8R8_2PLANE_444_UNORM, VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16,
                           VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16, VK_FORMAT_G16_B16R16_2PLANE_444_UNORM})) {
        const auto &exposed_extensions = physical_device_extensions.at(physicalDevice);

        if (api_version < VK_API_VERSION_1_3 && !exposed_extensions.vk_khr_maintenance5 &&
            !exposed_extensions.vk_ext_ycbcr_2plane_444_formats) {
            const char *vuid = context.error_obj.location.function == Func::vkGetPhysicalDeviceFormatProperties
                                   ? "VUID-vkGetPhysicalDeviceFormatProperties-None-12272"
                                   : "VUID-vkGetPhysicalDeviceFormatProperties2-None-12273";
            skip |=
                LogError(vuid, physicalDevice, context.error_obj.location.dot(Field::format), "is %s.", string_VkFormat(format));
        }
    }

    return skip;
}

bool Instance::manual_PreCallValidateGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
                                                                       VkFormatProperties *pFormatProperties,
                                                                       const Context &context) const {
    if (!pFormatProperties) {
        return false;
    }
    VkFormatProperties2 format_props_2 = vku::InitStructHelper();
    format_props_2.formatProperties = *pFormatProperties;
    return ValidateGetPhysicalDeviceFormatProperties2(physicalDevice, format, &format_props_2, context);
}

bool Instance::manual_PreCallValidateGetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format,
                                                                        VkFormatProperties2 *pFormatProperties,
                                                                        const Context &context) const {
    return ValidateGetPhysicalDeviceFormatProperties2(physicalDevice, format, pFormatProperties, context);
}

}  // namespace stateless
