/* 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 <sstream>
#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"
#include "utils/image_utils.h"
#include "utils/math_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);
    }
};

template <typename ExtensionState>
bool Instance::ValidateExtensionReqs(const ExtensionState& extensions, bool is_instance, 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
    }

    // Each entry in info.requirements is an "OR group" of required extensions:
    // In each group only one extension needs to be enabled for the group to be satisfied,
    // but all groups need to satisfied.
    // In practice as of writing, almost all groups have one element.
    std::vector<std::string> missing;
    for (const auto& or_group : info.requirements) {
        const bool is_any_required_ext_enabled = std::any_of(
            or_group.begin(), or_group.end(), [&extensions](const auto& req) { return IsExtEnabled(extensions.*(req.enabled)); });

        if (is_any_required_ext_enabled) {
            continue;
        }

        // Group not satisfied, log it in error message
        std::ostringstream group_ss;
        for (uint32_t i = 0; i < or_group.size(); i++) {
            if (i > 0) {
                group_ss << " or ";
            }
            group_ss << or_group[i].name;
            if (!is_instance) {
                vvl::Extension missing_extension = GetExtension(or_group[i].name);
                if (IsInstanceExtension(missing_extension)) {
                    group_ss << " (instance extension, which needs to be added to VkInstanceCreateInfo::ppEnabledExtensionNames)";
                }
            }
        }
        missing.push_back(group_ss.str());
    }

    if (missing.empty()) {
        return skip;
    }

    // Provide a better error message if instance or device (since device can depend on instance level extensions)
    if (is_instance) {
        std::ostringstream ss;
        ss << "Missing extension" << ((missing.size() > 1) ? "s" : "") << " required to enable instance extension "
           << String(extension) << ":\n";
        for (const auto& missing_name : missing) {
            ss << " - " << missing_name << "\n";
        }
        skip |= LogError("VUID-vkCreateInstance-ppEnabledExtensionNames-01388", instance, extension_loc, "%s", ss.str().c_str());

    } else {
        std::ostringstream ss;
        ss << "Missing extension" << ((missing.size() > 1) ? "s" : "") << " required to enable device extension "
           << String(extension) << ":\n";
        for (const auto& missing_name : missing) {
            ss << " - " << missing_name << "\n";
        }
        skip |= LogError("VUID-vkCreateDevice-ppEnabledExtensionNames-01387", instance, extension_loc, "%s", ss.str().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, true, 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 and returned in 1.4.347 as an explicit "set to null/zero"
    // https://gitlab.khronos.org/vulkan/vulkan/-/issues/4725
    // https://gitlab.khronos.org/vulkan/vulkan/-/merge_requests/8096/
    if (pCreateInfo->enabledLayerCount != 0) {
        skip |= LogError("VUID-VkDeviceCreateInfo-enabledLayerCount-12384", physicalDevice,
                         create_info_loc.dot(Field::enabledLayerCount),
                         "is %" PRIu32
                         " (not zero).\nDevice Layers have never worked since Vulkan 1.0 and only Instance Layers should be used "
                         "instead: https://docs.vulkan.org/spec/latest/appendices/legacy.html#legacy-devicelayers",
                         pCreateInfo->enabledLayerCount);
    } else if (pCreateInfo->ppEnabledLayerNames) {
        skip |= LogError("VUID-VkDeviceCreateInfo-ppEnabledLayerNames-12385", physicalDevice,
                         create_info_loc.dot(Field::ppEnabledLayerNames),
                         "is %p (not null).\nDevice Layers have never worked since Vulkan 1.0 and only Instance Layers should be "
                         "used instead: https://docs.vulkan.org/spec/latest/appendices/legacy.html#legacy-devicelayers",
                         pCreateInfo->ppEnabledLayerNames);
    }

    // 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, false, 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::pQueueCreateInfos, i).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 has_stencil_usage =
            vku::FindStructInPNextChain<VkImageStencilUsageCreateInfo>(pImageFormatInfo->pNext) != nullptr;
        const auto has_stencil_usage_2 =
            vku::FindStructInPNextChain<VkImageStencilUsage2CreateInfoKHR>(pImageFormatInfo->pNext) != nullptr;
        if (has_stencil_usage && has_stencil_usage_2) {
            skip |= LogError("VUID-VkImageCreateInfo-pNext-12442", physicalDevice, format_info_loc.dot(Field::pNext),
                             "contains both VkImageStencilUsageCreateInfo and VkImageStencilUsage2CreateInfoKHR.");
        }
        const auto stencil_usage = GetImageStencilUsageFlags(pImageFormatInfo->pNext);
        if (stencil_usage.has_value()) {
            if ((stencil_usage.value() & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0) {
                VkImageUsageFlags2KHR 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 ((stencil_usage.value() & ~legal_flags) != 0) {
                    const char* vuid = has_stencil_usage_2 ? "VUID-VkImageStencilUsage2CreateInfoKHR-stencilUsage-12443"
                                                           : "VUID-VkImageStencilUsageCreateInfo-stencilUsage-02539";
                    Location stencil_usage_loc =
                        has_stencil_usage_2 ? format_info_loc.pNext(Struct::VkImageStencilUsage2CreateInfoKHR, Field::stencilUsage)
                                            : format_info_loc.pNext(Struct::VkImageStencilUsageCreateInfo, Field::stencilUsage);
                    skip |= LogError(vuid, physicalDevice, stencil_usage_loc, "is %s.",
                                     string_VkImageUsageFlags2KHR(stencil_usage.value()).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) {
                    // The VU says the feature, but really is the extension. Some drivers will ignore vkGetPhysicalDeviceProperties2
                    // pNext structs if the extension is not enabled
                    if (IsExtSupported(extensions.vk_khr_maintenance11)) {
                        if (image_drm_format->queueFamilyIndexCount == 0) {
                            skip |= LogError(
                                "VUID-VkPhysicalDeviceImageDrmFormatModifierInfoEXT-maintenance11-13351", physicalDevice,
                                format_info_loc.pNext(Struct::VkPhysicalDeviceImageDrmFormatModifierInfoEXT, Field::sharingMode),
                                "is VK_SHARING_MODE_CONCURRENT, but queueFamilyIndexCount is 0 (needs to be at least 1).");
                        }
                    } else 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
                            " (Needs to be at least 2)\nHint: queueFamilyIndexCount can be 1 if the VK_KHR_maintenance11 extension "
                            "is supported on the device.",
                            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 does 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 (Use vkGetPhysicalDeviceImageFormatProperties2 instead).");
    }

    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);
}

bool Instance::manual_PreCallValidateGetPhysicalDeviceCooperativeMatrixProperties2EXT(
    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceCooperativeMatrixInfo2EXT* pCooperativeMatrixInfo,
    uint32_t* pPropertyCount, VkCooperativeMatrixProperties2EXT* pProperties, const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;
    const Location info_loc = error_obj.location.dot(Field::pCooperativeMatrixInfo);

    // We can't use SpecialSupported because this is at Instance level
    // This makes a bit of hard assumption VK_KHR_maintenance5 is supported for anyone who supports this CoopMat extension such that
    // we can query these features here
    VkPhysicalDeviceCooperativeMatrixMaintenance1FeaturesEXT cooperative_matrix_maintenance1 = vku::InitStructHelper();
    VkPhysicalDeviceCooperativeMatrix2FeaturesNV cooperative_matrix2 = vku::InitStructHelper(&cooperative_matrix_maintenance1);
    VkPhysicalDeviceSubgroupSizeControlFeatures subgroup_size_control = vku::InitStructHelper(&cooperative_matrix2);
    VkPhysicalDeviceFeatures2 features2 = vku::InitStructHelper(&subgroup_size_control);
    DispatchGetPhysicalDeviceFeatures2Helper(api_version, physicalDevice, &features2);

    if (!cooperative_matrix_maintenance1.cooperativeMatrixProperties2) {
        return LogError("VUID-vkGetPhysicalDeviceCooperativeMatrixProperties2EXT-cooperativeMatrixProperties2-13371",
                        physicalDevice, error_obj.location, "cooperativeMatrixProperties2 is not supported by physicalDevice.");
    }

    const VkScopeKHR scope = pCooperativeMatrixInfo->scope;
    const uint32_t invocations = pCooperativeMatrixInfo->invocations;
    const uint32_t subgroup_size = pCooperativeMatrixInfo->subgroupSize;

    if (scope != VK_SCOPE_SUBGROUP_KHR && scope != VK_SCOPE_WORKGROUP_KHR) {
        skip |= LogError("VUID-VkPhysicalDeviceCooperativeMatrixInfo2EXT-scope-13372", physicalDevice, info_loc.dot(Field::scope),
                         "is %s, but must be VK_SCOPE_SUBGROUP_KHR or VK_SCOPE_WORKGROUP_KHR.", string_VkScopeKHR(scope));
    }

    if (subgroup_size != 0 && !IsPowerOfTwo(subgroup_size)) {
        skip |= LogError("VUID-VkPhysicalDeviceCooperativeMatrixInfo2EXT-subgroupSize-13374", physicalDevice,
                         info_loc.dot(Field::subgroupSize), "is %" PRIu32 ", which is not a power of two.", subgroup_size);
    }

    if (scope == VK_SCOPE_SUBGROUP_KHR && subgroup_size != 0) {
        if (subgroup_size_control.subgroupSizeControl) {
            VkPhysicalDeviceSubgroupSizeControlProperties subgroup_size_control_props = vku::InitStructHelper();
            VkPhysicalDeviceProperties2 props2 = vku::InitStructHelper(&subgroup_size_control_props);
            DispatchGetPhysicalDeviceProperties2Helper(api_version, physicalDevice, &props2);

            if (subgroup_size < subgroup_size_control_props.minSubgroupSize) {
                skip |=
                    LogError("VUID-VkPhysicalDeviceCooperativeMatrixInfo2EXT-scope-13375", physicalDevice,
                             info_loc.dot(Field::subgroupSize), "is %" PRIu32 ", which is less than minSubgroupSize (%" PRIu32 ").",
                             subgroup_size, subgroup_size_control_props.minSubgroupSize);
            }
            if (subgroup_size > subgroup_size_control_props.maxSubgroupSize) {
                skip |= LogError("VUID-VkPhysicalDeviceCooperativeMatrixInfo2EXT-scope-13376", physicalDevice,
                                 info_loc.dot(Field::subgroupSize),
                                 "is %" PRIu32 ", which is greater than maxSubgroupSize (%" PRIu32 ").", subgroup_size,
                                 subgroup_size_control_props.maxSubgroupSize);
            }
        } else {
            VkPhysicalDeviceSubgroupProperties subgroup_props = vku::InitStructHelper();
            VkPhysicalDeviceProperties2 props2 = vku::InitStructHelper(&subgroup_props);
            DispatchGetPhysicalDeviceProperties2Helper(api_version, physicalDevice, &props2);

            if (subgroup_size != subgroup_props.subgroupSize) {
                skip |= LogError("VUID-VkPhysicalDeviceCooperativeMatrixInfo2EXT-scope-13377", physicalDevice,
                                 info_loc.dot(Field::subgroupSize),
                                 "is %" PRIu32 ", but subgroupSizeControl is not supported and subgroupSize is %" PRIu32 ".",
                                 subgroup_size, subgroup_props.subgroupSize);
            }
        }
    }

    if (scope == VK_SCOPE_WORKGROUP_KHR) {
        if (!cooperative_matrix2.cooperativeMatrixWorkgroupScope) {
            skip |= LogError("VUID-VkPhysicalDeviceCooperativeMatrixInfo2EXT-cooperativeMatrixWorkgroupScope-13373", physicalDevice,
                             info_loc.dot(Field::scope),
                             "is VK_SCOPE_WORKGROUP_KHR, but cooperativeMatrixWorkgroupScope is not supported.\nWith "
                             "VK_EXT_cooperative_matrix_maintenance1 alone, scope must be VK_SCOPE_SUBGROUP_KHR.");
        } else {
            VkPhysicalDeviceCooperativeMatrix2PropertiesNV cooperative_matrix2_props = vku::InitStructHelper();
            VkPhysicalDeviceProperties2 props2 = vku::InitStructHelper(&cooperative_matrix2_props);
            DispatchGetPhysicalDeviceProperties2Helper(api_version, physicalDevice, &props2);

            if (invocations > cooperative_matrix2_props.cooperativeMatrixWorkgroupScopeMaxWorkgroupSize) {
                skip |= LogError(
                    "VUID-VkPhysicalDeviceCooperativeMatrixInfo2EXT-scope-13380", physicalDevice, info_loc.dot(Field::invocations),
                    "is %" PRIu32 ", which is greater than cooperativeMatrixWorkgroupScopeMaxWorkgroupSize (%" PRIu32 ").",
                    invocations, cooperative_matrix2_props.cooperativeMatrixWorkgroupScopeMaxWorkgroupSize);
            }
        }
        if (!IsPowerOfTwo(invocations)) {
            skip |= LogError("VUID-VkPhysicalDeviceCooperativeMatrixInfo2EXT-invocations-13378", physicalDevice,
                             info_loc.dot(Field::invocations), "is %" PRIu32 ", which is not a power of two.", invocations);
        }
        if (subgroup_size != 0 && (invocations % subgroup_size) != 0) {
            skip |= LogError("VUID-VkPhysicalDeviceCooperativeMatrixInfo2EXT-subgroupSize-13379", physicalDevice,
                             info_loc.dot(Field::invocations),
                             "is %" PRIu32 ", which is not a multiple of subgroupSize (%" PRIu32 ").", invocations, subgroup_size);
        }

    } else if (invocations != 0) {
        skip |= LogError("VUID-VkPhysicalDeviceCooperativeMatrixInfo2EXT-invocations-13381", physicalDevice,
                         info_loc.dot(Field::invocations), "is %" PRIu32 ", but scope is %s, so invocations must be zero.",
                         invocations, string_VkScopeKHR(scope));
    }

    return skip;
}

}  // namespace stateless
