/* Copyright (c) 2015-2023 The Khronos Group Inc.
 * Copyright (c) 2015-2023 Valve Corporation
 * Copyright (c) 2015-2023 LunarG, Inc.
 * Copyright (C) 2015-2023 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 "stateless/stateless_validation.h"
#include "generated/enum_flag_bits.h"

bool StatelessValidation::ValidateCoarseSampleOrderCustomNV(const VkCoarseSampleOrderCustomNV *order,
                                                            const Location &order_loc) const {
    bool skip = false;

    struct SampleOrderInfo {
        VkShadingRatePaletteEntryNV shadingRate;
        uint32_t width;
        uint32_t height;
    };

    // All palette entries with more than one pixel per fragment
    constexpr std::array sample_order_infos = {
        SampleOrderInfo{VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV, 1, 2},
        SampleOrderInfo{VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X1_PIXELS_NV, 2, 1},
        SampleOrderInfo{VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X2_PIXELS_NV, 2, 2},
        SampleOrderInfo{VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X2_PIXELS_NV, 4, 2},
        SampleOrderInfo{VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X4_PIXELS_NV, 2, 4},
        SampleOrderInfo{VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV, 4, 4},
    };

    const SampleOrderInfo *sample_order_info;
    uint32_t info_idx = 0;
    for (sample_order_info = nullptr; info_idx < sample_order_infos.size(); ++info_idx) {
        if (sample_order_infos[info_idx].shadingRate == order->shadingRate) {
            sample_order_info = &sample_order_infos[info_idx];
            break;
        }
    }

    if (sample_order_info == nullptr) {
        skip |= LogError("VUID-VkCoarseSampleOrderCustomNV-shadingRate-02073", device, order_loc,
                         "shadingRate must be a shading rate "
                         "that generates fragments with more than one pixel.");
        return skip;
    }

    if (order->sampleCount == 0 || (order->sampleCount & (order->sampleCount - 1)) ||
        !(order->sampleCount & device_limits.framebufferNoAttachmentsSampleCounts)) {
        skip |= LogError("VUID-VkCoarseSampleOrderCustomNV-sampleCount-02074", device, order_loc,
                         "sampleCount (=%" PRIu32
                         ") must "
                         "correspond to a sample count enumerated in VkSampleCountFlags whose corresponding bit "
                         "is set in framebufferNoAttachmentsSampleCounts.",
                         order->sampleCount);
    }

    if (order->sampleLocationCount != order->sampleCount * sample_order_info->width * sample_order_info->height) {
        skip |= LogError("VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02075", device, order_loc,
                         "sampleLocationCount (=%" PRIu32
                         ") must "
                         "be equal to the product of sampleCount (=%" PRIu32
                         "), the fragment width for shadingRate "
                         "(=%" PRIu32 "), and the fragment height for shadingRate (=%" PRIu32 ").",
                         order->sampleLocationCount, order->sampleCount, sample_order_info->width, sample_order_info->height);
    }

    if (order->sampleLocationCount > phys_dev_ext_props.shading_rate_image_props.shadingRateMaxCoarseSamples) {
        skip |= LogError(
            "VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02076", device, order_loc,
            "sampleLocationCount (=%" PRIu32
            ") must "
            "be less than or equal to VkPhysicalDeviceShadingRateImagePropertiesNV shadingRateMaxCoarseSamples (=%" PRIu32 ").",
            order->sampleLocationCount, phys_dev_ext_props.shading_rate_image_props.shadingRateMaxCoarseSamples);
    }

    // Accumulate a bitmask tracking which (x,y,sample) tuples are seen. Expect
    // the first width*height*sampleCount bits to all be set. Note: There is no
    // guarantee that 64 bits is enough, but practically it's unlikely for an
    // implementation to support more than 32 bits for samplemask.
    assert(phys_dev_ext_props.shading_rate_image_props.shadingRateMaxCoarseSamples <= 64);
    uint64_t sample_locations_mask = 0;
    for (uint32_t i = 0; i < order->sampleLocationCount; ++i) {
        const VkCoarseSampleLocationNV *sample_loc = &order->pSampleLocations[i];
        if (sample_loc->pixelX >= sample_order_info->width) {
            skip |= LogError("VUID-VkCoarseSampleLocationNV-pixelX-02078", device, order_loc,
                             "pixelX must be less than the width (in pixels) of the fragment.");
        }
        if (sample_loc->pixelY >= sample_order_info->height) {
            skip |= LogError("VUID-VkCoarseSampleLocationNV-pixelY-02079", device, order_loc,
                             "pixelY must be less than the height (in pixels) of the fragment.");
        }
        if (sample_loc->sample >= order->sampleCount) {
            skip |= LogError("VUID-VkCoarseSampleLocationNV-sample-02080", device, order_loc,
                             "sample must be less than the number of coverage samples in each pixel belonging to the fragment.");
        }
        uint32_t idx =
            sample_loc->sample + order->sampleCount * (sample_loc->pixelX + sample_order_info->width * sample_loc->pixelY);
        sample_locations_mask |= 1ULL << idx;
    }

    uint64_t expected_mask = (order->sampleLocationCount == 64) ? ~0ULL : ((1ULL << order->sampleLocationCount) - 1);
    if (sample_locations_mask != expected_mask) {
        skip |= LogError(
            "VUID-VkCoarseSampleOrderCustomNV-pSampleLocations-02077", device, order_loc,
            "The array pSampleLocations must contain exactly one entry for "
            "every combination of valid values for pixelX, pixelY, and sample in the structure VkCoarseSampleOrderCustomNV.");
    }

    return skip;
}

bool StatelessValidation::manual_PreCallValidateCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo,
                                                              const VkAllocationCallbacks *pAllocator, VkSampler *pSampler,
                                                              const ErrorObject &error_obj) const {
    bool skip = false;

    if (pCreateInfo == nullptr) {
        return skip;
    }
    const Location create_info_loc = error_obj.location.dot(Field::pCreateInfo);
    const auto &features = physical_device_features;
    const auto &limits = device_limits;

    if (pCreateInfo->anisotropyEnable == VK_TRUE) {
        if (!IsBetweenInclusive(pCreateInfo->maxAnisotropy, 1.0F, limits.maxSamplerAnisotropy)) {
            skip |= LogError("VUID-VkSamplerCreateInfo-anisotropyEnable-01071", device, create_info_loc.dot(Field::maxAnisotropy),
                             "is %f but must be in the range of [1.0, %f] (maxSamplerAnistropy).", pCreateInfo->maxAnisotropy,
                             limits.maxSamplerAnisotropy);
        }

        // Anistropy cannot be enabled in sampler unless enabled as a feature
        if (features.samplerAnisotropy == VK_FALSE) {
            skip |=
                LogError("VUID-VkSamplerCreateInfo-anisotropyEnable-01070", device, create_info_loc.dot(Field::anisotropyEnable),
                         "is VK_TRUE but the samplerAnisotropy feature was not enabled.");
        }
    }

    if (pCreateInfo->unnormalizedCoordinates == VK_TRUE) {
        if (pCreateInfo->minFilter != pCreateInfo->magFilter) {
            skip |= LogError("VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01072", device,
                             create_info_loc.dot(Field::unnormalizedCoordinates),
                             "is VK_TRUE, but minFilter (%s) is different then magFilter (%s).",
                             string_VkFilter(pCreateInfo->minFilter), string_VkFilter(pCreateInfo->magFilter));
        }
        if (pCreateInfo->mipmapMode != VK_SAMPLER_MIPMAP_MODE_NEAREST) {
            skip |= LogError("VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01073", device,
                             create_info_loc.dot(Field::unnormalizedCoordinates),
                             "is VK_TRUE, but mipmapMode (%s) must be VK_SAMPLER_MIPMAP_MODE_NEAREST.",
                             string_VkSamplerMipmapMode(pCreateInfo->mipmapMode));
        }
        if (pCreateInfo->minLod != 0.0f || pCreateInfo->maxLod != 0.0f) {
            skip |= LogError("VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01074", device,
                             create_info_loc.dot(Field::unnormalizedCoordinates),
                             "is VK_TRUE, but minLod (%f) and maxLod (%f) must both be zero.", pCreateInfo->minLod,
                             pCreateInfo->maxLod);
        }
        if ((pCreateInfo->addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE &&
             pCreateInfo->addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) ||
            (pCreateInfo->addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE &&
             pCreateInfo->addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)) {
            skip |= LogError("VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01075", device,
                             create_info_loc.dot(Field::unnormalizedCoordinates),
                             "is VK_TRUE, but addressModeU (%s) and addressModeV (%s) must both be "
                             "CLAMP_TO_EDGE or CLAMP_TO_BORDER.",
                             string_VkSamplerAddressMode(pCreateInfo->addressModeU),
                             string_VkSamplerAddressMode(pCreateInfo->addressModeV));
        }
        if (pCreateInfo->anisotropyEnable == VK_TRUE) {
            skip |= LogError("VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01076", device, create_info_loc,
                             "anisotropyEnable and unnormalizedCoordinates are both VK_TRUE.");
        }
        if (pCreateInfo->compareEnable == VK_TRUE) {
            skip |= LogError("VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01077", device, create_info_loc,
                             "compareEnable and unnormalizedCoordinates are both VK_TRUE.");
        }
    }

    // If compareEnable is VK_TRUE, compareOp must be a valid VkCompareOp value
    const auto *sampler_reduction = vku::FindStructInPNextChain<VkSamplerReductionModeCreateInfo>(pCreateInfo->pNext);
    if (pCreateInfo->compareEnable == VK_TRUE) {
        skip |= ValidateRangedEnum(create_info_loc.dot(Field::compareOp), "VkCompareOp", pCreateInfo->compareOp,
                                   "VUID-VkSamplerCreateInfo-compareEnable-01080");
        if (sampler_reduction != nullptr) {
            if (sampler_reduction->reductionMode != VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE) {
                skip |= LogError("VUID-VkSamplerCreateInfo-compareEnable-01423", device,
                                 create_info_loc.pNext(Struct::VkSamplerReductionModeCreateInfo, Field::reductionMode),
                                 "is %s but compareEnable is VK_TRUE.",
                                 string_VkSamplerReductionMode(sampler_reduction->reductionMode));
            }
        }
    }
    if (sampler_reduction && sampler_reduction->reductionMode != VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE) {
        if (!IsExtEnabled(device_extensions.vk_ext_filter_cubic)) {
            if (pCreateInfo->magFilter == VK_FILTER_CUBIC_EXT || pCreateInfo->minFilter == VK_FILTER_CUBIC_EXT) {
                skip |= LogError("VUID-VkSamplerCreateInfo-magFilter-07911", device,
                                 create_info_loc.pNext(Struct::VkSamplerReductionModeCreateInfo, Field::reductionMode),
                                 "is %s, magFilter is %s and minFilter is %s, but "
                                 "extension %s is not enabled.",
                                 string_VkSamplerReductionMode(sampler_reduction->reductionMode),
                                 string_VkFilter(pCreateInfo->magFilter), string_VkFilter(pCreateInfo->minFilter),
                                 VK_EXT_FILTER_CUBIC_EXTENSION_NAME);
            }
        }
    }

    // If any of addressModeU, addressModeV or addressModeW are VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, borderColor must be a
    // valid VkBorderColor value
    if ((pCreateInfo->addressModeU == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) ||
        (pCreateInfo->addressModeV == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) ||
        (pCreateInfo->addressModeW == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)) {
        skip |= ValidateRangedEnum(create_info_loc.dot(Field::borderColor), "VkBorderColor", pCreateInfo->borderColor,
                                   "VUID-VkSamplerCreateInfo-addressModeU-01078");
    }

    // Checks for the IMG cubic filtering extension
    if (IsExtEnabled(device_extensions.vk_img_filter_cubic)) {
        if ((pCreateInfo->anisotropyEnable == VK_TRUE) &&
            ((pCreateInfo->minFilter == VK_FILTER_CUBIC_IMG) || (pCreateInfo->magFilter == VK_FILTER_CUBIC_IMG))) {
            skip |= LogError("VUID-VkSamplerCreateInfo-magFilter-01081", device, create_info_loc,
                             "anisotropyEnable is VK_TRUE, but minFilter = %s and magFilter = %s",
                             string_VkFilter(pCreateInfo->minFilter), string_VkFilter(pCreateInfo->magFilter));
        }
    }

    // Check for valid Lod range
    if (pCreateInfo->minLod > pCreateInfo->maxLod) {
        skip |= LogError("VUID-VkSamplerCreateInfo-maxLod-01973", device, create_info_loc,
                         "minLod (%f) is greater than maxLod (%f)", pCreateInfo->minLod, pCreateInfo->maxLod);
    }

    // Check mipLodBias to device limit
    if (pCreateInfo->mipLodBias > limits.maxSamplerLodBias) {
        skip |= LogError("VUID-VkSamplerCreateInfo-mipLodBias-01069", device, create_info_loc.dot(Field::mipLodBias),
                         "(%f) is greater than maxSamplerLodBias (%f)", pCreateInfo->mipLodBias, limits.maxSamplerLodBias);
    }

    const auto *sampler_conversion = vku::FindStructInPNextChain<VkSamplerYcbcrConversionInfo>(pCreateInfo->pNext);
    if (sampler_conversion != nullptr) {
        if ((pCreateInfo->addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE) ||
            (pCreateInfo->addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE) ||
            (pCreateInfo->addressModeW != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE) || (pCreateInfo->anisotropyEnable != VK_FALSE) ||
            (pCreateInfo->unnormalizedCoordinates != VK_FALSE)) {
            skip |= LogError(
                "VUID-VkSamplerCreateInfo-addressModeU-01646", device, create_info_loc,
                "vkCreateSampler():  SamplerYCbCrConversion is enabled: "
                "addressModeU (%s), addressModeV (%s), addressModeW (%s) must be CLAMP_TO_EDGE, and anisotropyEnable (%s) "
                "and unnormalizedCoordinates (%s) must be VK_FALSE.",
                string_VkSamplerAddressMode(pCreateInfo->addressModeU), string_VkSamplerAddressMode(pCreateInfo->addressModeV),
                string_VkSamplerAddressMode(pCreateInfo->addressModeW), pCreateInfo->anisotropyEnable ? "VK_TRUE" : "VK_FALSE",
                pCreateInfo->unnormalizedCoordinates ? "VK_TRUE" : "VK_FALSE");
        }
    }

    if (pCreateInfo->flags & VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT) {
        if (pCreateInfo->minFilter != pCreateInfo->magFilter) {
            skip |= LogError("VUID-VkSamplerCreateInfo-flags-02574", device, create_info_loc.dot(Field::flags),
                             "includes VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT, but "
                             "minFilter (%s) and magFilter (%s) must be equal.",
                             string_VkFilter(pCreateInfo->minFilter), string_VkFilter(pCreateInfo->magFilter));
        }
        if (pCreateInfo->mipmapMode != VK_SAMPLER_MIPMAP_MODE_NEAREST) {
            skip |= LogError("VUID-VkSamplerCreateInfo-flags-02575", device, create_info_loc.dot(Field::flags),
                             "includes VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT, but "
                             "mipmapMode (%s) must be VK_SAMPLER_MIPMAP_MODE_NEAREST.",
                             string_VkSamplerMipmapMode(pCreateInfo->mipmapMode));
        }
        if (pCreateInfo->minLod != 0.0 || pCreateInfo->maxLod != 0.0) {
            skip |= LogError("VUID-VkSamplerCreateInfo-flags-02576", device, create_info_loc.dot(Field::flags),
                             "includes VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT, but "
                             "minLod (%f) and maxLod (%f) must be zero.",
                             pCreateInfo->minLod, pCreateInfo->maxLod);
        }
        if (((pCreateInfo->addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE) &&
             (pCreateInfo->addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)) ||
            ((pCreateInfo->addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE) &&
             (pCreateInfo->addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER))) {
            skip |= LogError("VUID-VkSamplerCreateInfo-flags-02577", device, create_info_loc.dot(Field::flags),
                             "includes VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT, "
                             "addressModeU (%s) and addressModeV (%s) must be "
                             "CLAMP_TO_EDGE or CLAMP_TO_BORDER",
                             string_VkSamplerAddressMode(pCreateInfo->addressModeU),
                             string_VkSamplerAddressMode(pCreateInfo->addressModeV));
        }
        if (pCreateInfo->anisotropyEnable) {
            skip |= LogError("VUID-VkSamplerCreateInfo-flags-02578", device, create_info_loc.dot(Field::flags),
                             "includes VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT, "
                             "but anisotropyEnable is VK_TRUE.");
        }
        if (pCreateInfo->compareEnable) {
            skip |= LogError("VUID-VkSamplerCreateInfo-flags-02579", device, create_info_loc.dot(Field::flags),
                             "includes VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT, "
                             "but compareEnable is VK_TRUE.");
        }
        if (pCreateInfo->unnormalizedCoordinates) {
            skip |= LogError("VUID-VkSamplerCreateInfo-flags-02580", device, create_info_loc.dot(Field::flags),
                             "includes VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT, "
                             "but unnormalizedCoordinates is VK_TRUE.");
        }
    }

    if (pCreateInfo->borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT ||
        pCreateInfo->borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT) {
        if (!IsExtEnabled(device_extensions.vk_ext_custom_border_color)) {
            skip |= LogError(kVUID_PVError_ExtensionNotEnabled, device, create_info_loc.dot(Field::borderColor),
                             "is %s but %s is not enabled.", string_VkBorderColor(pCreateInfo->borderColor),
                             VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME);
        }
        auto custom_create_info = vku::FindStructInPNextChain<VkSamplerCustomBorderColorCreateInfoEXT>(pCreateInfo->pNext);
        if (!custom_create_info) {
            skip |= LogError("VUID-VkSamplerCreateInfo-borderColor-04011", device, create_info_loc.dot(Field::borderColor),
                             "is %s but there is no VkSamplerCustomBorderColorCreateInfoEXT "
                             "struct in pNext chain.",
                             string_VkBorderColor(pCreateInfo->borderColor));
        } else {
            if ((custom_create_info->format != VK_FORMAT_UNDEFINED) && !vkuFormatIsDepthAndStencil(custom_create_info->format) &&
                ((pCreateInfo->borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT && !vkuFormatIsSampledInt(custom_create_info->format)) ||
                 (pCreateInfo->borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT &&
                  !vkuFormatIsSampledFloat(custom_create_info->format)))) {
                skip |= LogError("VUID-VkSamplerCustomBorderColorCreateInfoEXT-format-07605", device,
                                 create_info_loc.pNext(Struct::VkSamplerCustomBorderColorCreateInfoEXT, Field::format),
                                 "%s does not match borderColor (%s).", string_VkFormat(custom_create_info->format),
                                 string_VkBorderColor(pCreateInfo->borderColor));
            }
        }
    }

    const auto *border_color_component_mapping =
        vku::FindStructInPNextChain<VkSamplerBorderColorComponentMappingCreateInfoEXT>(pCreateInfo->pNext);
    if (border_color_component_mapping) {
        const auto *border_color_swizzle_features =
            vku::FindStructInPNextChain<VkPhysicalDeviceBorderColorSwizzleFeaturesEXT>(device_createinfo_pnext);
        bool border_color_swizzle_features_enabled =
            border_color_swizzle_features && border_color_swizzle_features->borderColorSwizzle;
        if (!border_color_swizzle_features_enabled) {
            skip |=
                LogError("VUID-VkSamplerBorderColorComponentMappingCreateInfoEXT-borderColorSwizzle-06437", device, create_info_loc,
                         "The borderColorSwizzle feature must be enabled to use "
                         "VkPhysicalDeviceBorderColorSwizzleFeaturesEXT");
        }
    }

    // VK_QCOM_image_processing
    if ((pCreateInfo->flags & VK_SAMPLER_CREATE_IMAGE_PROCESSING_BIT_QCOM) != 0) {
        if ((pCreateInfo->minFilter != VK_FILTER_NEAREST) || (pCreateInfo->magFilter != VK_FILTER_NEAREST)) {
            skip |= LogError("VUID-VkSamplerCreateInfo-flags-06964", device, create_info_loc.dot(Field::flags),
                             "includes VK_SAMPLER_CREATE_IMAGE_PROCESSING_BIT_QCOM, "
                             "minFilter (%s) must be VK_FILTER_NEAREST and "
                             "magFilter (%s) must be VK_FILTER_NEAREST.",
                             string_VkFilter(pCreateInfo->minFilter), string_VkFilter(pCreateInfo->magFilter));
        }
        if (pCreateInfo->mipmapMode != VK_SAMPLER_MIPMAP_MODE_NEAREST) {
            skip |= LogError("VUID-VkSamplerCreateInfo-flags-06965", device, create_info_loc.dot(Field::flags),
                             "includes VK_SAMPLER_CREATE_IMAGE_PROCESSING_BIT_QCOM, "
                             "mipmapMode (%s) must be VK_SAMPLER_MIPMAP_MODE_NEAREST.",
                             string_VkSamplerMipmapMode(pCreateInfo->mipmapMode));
        }
        if ((pCreateInfo->minLod != 0) || (pCreateInfo->maxLod != 0)) {
            skip |= LogError("VUID-VkSamplerCreateInfo-flags-06966", device, create_info_loc.dot(Field::flags),
                             "includes VK_SAMPLER_CREATE_IMAGE_PROCESSING_BIT_QCOM, "
                             "minLod (%f) and maxLod (%f) must be 0.",
                             pCreateInfo->minLod, pCreateInfo->maxLod);
        }
        if (((pCreateInfo->addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE) &&
             (pCreateInfo->addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)) ||
            ((pCreateInfo->addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE) &&
             (pCreateInfo->addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER))) {
            skip |= LogError("VUID-VkSamplerCreateInfo-flags-06967", device, create_info_loc.dot(Field::flags),
                             "includes VK_SAMPLER_CREATE_IMAGE_PROCESSING_BIT_QCOM, "
                             "addressModeU (%s) and addressModeV (%s) must be either "
                             "VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE or VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER.",
                             string_VkSamplerAddressMode(pCreateInfo->addressModeU),
                             string_VkSamplerAddressMode(pCreateInfo->addressModeV));
        }
        if (((pCreateInfo->addressModeU == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) ||
             (pCreateInfo->addressModeV == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)) &&
            (pCreateInfo->borderColor != VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK)) {
            skip |=
                LogError("VUID-VkSamplerCreateInfo-flags-06968", device, create_info_loc.dot(Field::flags),
                         "includes VK_SAMPLER_CREATE_IMAGE_PROCESSING_BIT_QCOM, "
                         "and if addressModeU (%s) or addressModeV (%s) are "
                         "VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, then"
                         "borderColor (%s) must be VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK.",
                         string_VkSamplerAddressMode(pCreateInfo->addressModeU),
                         string_VkSamplerAddressMode(pCreateInfo->addressModeV), string_VkBorderColor(pCreateInfo->borderColor));
        }
        if (pCreateInfo->anisotropyEnable) {
            skip |= LogError("VUID-VkSamplerCreateInfo-flags-06969", device, create_info_loc.dot(Field::flags),
                             "includes VK_SAMPLER_CREATE_IMAGE_PROCESSING_BIT_QCOM, "
                             "but anisotropyEnable is VK_TRUE.");
        }
        if (pCreateInfo->compareEnable) {
            skip |= LogError("VUID-VkSamplerCreateInfo-flags-06970", device, create_info_loc.dot(Field::flags),
                             "includes VK_SAMPLER_CREATE_IMAGE_PROCESSING_BIT_QCOM, "
                             "but compareEnable is VK_TRUE.");
        }
    }

    return skip;
}

bool StatelessValidation::ValidateMutableDescriptorTypeCreateInfo(const VkDescriptorSetLayoutCreateInfo &create_info,
                                                                  const VkMutableDescriptorTypeCreateInfoEXT &mutable_create_info,
                                                                  const Location &loc) const {
    bool skip = false;

    for (uint32_t i = 0; i < create_info.bindingCount; ++i) {
        const Location binding_loc = loc.dot(Field::pBindings, i);
        uint32_t mutable_type_count = 0;
        if (mutable_create_info.mutableDescriptorTypeListCount > i) {
            mutable_type_count = mutable_create_info.pMutableDescriptorTypeLists[i].descriptorTypeCount;
        }
        if (create_info.pBindings[i].descriptorType == VK_DESCRIPTOR_TYPE_MUTABLE_EXT) {
            if (mutable_type_count == 0) {
                skip |= LogError(
                    "VUID-VkMutableDescriptorTypeListEXT-descriptorTypeCount-04597", device, binding_loc.dot(Field::descriptorType),
                    "is VK_DESCRIPTOR_TYPE_MUTABLE_EXT, but "
                    "VkMutableDescriptorTypeCreateInfoEXT::pMutableDescriptorTypeLists[%" PRIu32 "].descriptorTypeCount is 0.",
                    i);
            }
        } else {
            if (mutable_type_count > 0) {
                skip |= LogError(
                    "VUID-VkMutableDescriptorTypeListEXT-descriptorTypeCount-04599", device, binding_loc.dot(Field::descriptorType),
                    "is %s, but "
                    "VkMutableDescriptorTypeCreateInfoEXT::pMutableDescriptorTypeLists[%" PRIu32 "].descriptorTypeCount is not 0.",
                    string_VkDescriptorType(create_info.pBindings[i].descriptorType), i);
            }
        }
    }

    for (uint32_t j = 0; j < mutable_create_info.mutableDescriptorTypeListCount; ++j) {
        const Location mutable_loc = loc.pNext(Struct::VkMutableDescriptorTypeCreateInfoEXT, Field::pMutableDescriptorTypeLists, j);
        for (uint32_t k = 0; k < mutable_create_info.pMutableDescriptorTypeLists[j].descriptorTypeCount; ++k) {
            const Location type_loc = mutable_loc.dot(Field::pDescriptorTypes, k);
            switch (mutable_create_info.pMutableDescriptorTypeLists[j].pDescriptorTypes[k]) {
                case VK_DESCRIPTOR_TYPE_MUTABLE_EXT:
                    skip |= LogError("VUID-VkMutableDescriptorTypeListEXT-pDescriptorTypes-04600", device, type_loc,
                                     "is VK_DESCRIPTOR_TYPE_MUTABLE_EXT.");
                    break;
                case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
                    skip |= LogError("VUID-VkMutableDescriptorTypeListEXT-pDescriptorTypes-04601", device, type_loc,
                                     "is VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC.");
                    break;
                case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
                    skip |= LogError("VUID-VkMutableDescriptorTypeListEXT-pDescriptorTypes-04602", device, type_loc,
                                     "is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC.");
                    break;
                case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
                    skip |= LogError("VUID-VkMutableDescriptorTypeListEXT-pDescriptorTypes-04603", device, type_loc,
                                     "is VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT.");
                    break;
                default:
                    break;
            }
            for (uint32_t l = k + 1; l < mutable_create_info.pMutableDescriptorTypeLists[j].descriptorTypeCount; ++l) {
                if (mutable_create_info.pMutableDescriptorTypeLists[j].pDescriptorTypes[k] ==
                    mutable_create_info.pMutableDescriptorTypeLists[j].pDescriptorTypes[l]) {
                    skip |=
                        LogError("VUID-VkMutableDescriptorTypeListEXT-pDescriptorTypes-04598", device, type_loc,
                                 "and pDescriptorTypes[%" PRIu32 "] are both %s.", l,
                                 string_VkDescriptorType(mutable_create_info.pMutableDescriptorTypeLists[j].pDescriptorTypes[k]));
                }
            }
        }
    }

    return skip;
}

bool StatelessValidation::manual_PreCallValidateCreateDescriptorSetLayout(VkDevice device,
                                                                          const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
                                                                          const VkAllocationCallbacks *pAllocator,
                                                                          VkDescriptorSetLayout *pSetLayout,
                                                                          const ErrorObject &error_obj) const {
    bool skip = false;

    const auto *mutable_descriptor_type = vku::FindStructInPNextChain<VkMutableDescriptorTypeCreateInfoEXT>(pCreateInfo->pNext);
    const auto *mutable_descriptor_type_features =
        vku::FindStructInPNextChain<VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT>(device_createinfo_pnext);
    bool mutable_descriptor_type_features_enabled =
        mutable_descriptor_type_features && mutable_descriptor_type_features->mutableDescriptorType == VK_TRUE;
    const Location create_info_loc = error_obj.location.dot(Field::pCreateInfo);

    // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
    if (pCreateInfo->pBindings != nullptr) {
        for (uint32_t i = 0; i < pCreateInfo->bindingCount; ++i) {
            const Location binding_loc = create_info_loc.dot(Field::pBindings, i);
            if (pCreateInfo->pBindings[i].descriptorCount != 0) {
                // If descriptorCount is not 0, stageFlags must be a valid combination of VkShaderStageFlagBits values
                if ((pCreateInfo->pBindings[i].stageFlags != 0) &&
                    ((pCreateInfo->pBindings[i].stageFlags & (~AllVkShaderStageFlagBits)) != 0)) {
                    skip |= LogError("VUID-VkDescriptorSetLayoutBinding-descriptorCount-00283", device,
                                     binding_loc.dot(Field::descriptorCount),
                                     "is %" PRIu32 " but stageFlags is invalid (0x%" PRIx32 ").",
                                     pCreateInfo->pBindings[i].descriptorCount, pCreateInfo->pBindings[i].stageFlags);
                }

                if ((pCreateInfo->pBindings[i].descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) &&
                    (pCreateInfo->pBindings[i].stageFlags != 0) &&
                    (pCreateInfo->pBindings[i].stageFlags != VK_SHADER_STAGE_FRAGMENT_BIT)) {
                    skip |= LogError("VUID-VkDescriptorSetLayoutBinding-descriptorType-01510", device,
                                     binding_loc.dot(Field::stageFlags),
                                     "is %s but descriptorType is VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT.",
                                     string_VkShaderStageFlags(pCreateInfo->pBindings[i].stageFlags).c_str());
                }

                if (pCreateInfo->pBindings[i].descriptorType == VK_DESCRIPTOR_TYPE_MUTABLE_EXT) {
                    if (mutable_descriptor_type) {
                        if (i >= mutable_descriptor_type->mutableDescriptorTypeListCount) {
                            skip |= LogError("VUID-VkDescriptorSetLayoutCreateInfo-pBindings-07303", device,
                                             binding_loc.pNext(Struct::VkMutableDescriptorTypeCreateInfoEXT,
                                                               Field::mutableDescriptorTypeListCount),
                                             "is %" PRIu32 " but descriptorType is VK_DESCRIPTOR_TYPE_MUTABLE_EXT but ",
                                             mutable_descriptor_type->mutableDescriptorTypeListCount);
                        }
                    } else {
                        skip |= LogError("VUID-VkDescriptorSetLayoutCreateInfo-pBindings-07303", device,
                                         binding_loc.dot(Field::descriptorType),
                                         "is VK_DESCRIPTOR_TYPE_MUTABLE_EXT but VkMutableDescriptorTypeCreateInfoEXT is not "
                                         "included in the pNext chain.");
                    }
                    if (pCreateInfo->pBindings[i].pImmutableSamplers) {
                        skip |= LogError("VUID-VkDescriptorSetLayoutCreateInfo-descriptorType-04594", device,
                                         binding_loc.dot(Field::descriptorType),
                                         "is VK_DESCRIPTOR_TYPE_MUTABLE_EXT but pImmutableSamplers is not NULL.");
                    }
                    if (!mutable_descriptor_type_features_enabled) {
                        skip |= LogError("VUID-VkDescriptorSetLayoutCreateInfo-mutableDescriptorType-04595", device,
                                         binding_loc.dot(Field::descriptorType),
                                         "is VK_DESCRIPTOR_TYPE_MUTABLE_EXT but "
                                         "mutableDescriptorType feature was not enabled.");
                    }
                }

                if (pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR &&
                    pCreateInfo->pBindings[i].descriptorType == VK_DESCRIPTOR_TYPE_MUTABLE_EXT) {
                    skip |=
                        LogError("VUID-VkDescriptorSetLayoutCreateInfo-flags-04591", device, binding_loc.dot(Field::descriptorType),
                                 "is VK_DESCRIPTOR_TYPE_MUTABLE_EXT, but flags includes "
                                 "VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR.");
                }

                if (pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT &&
                    ((pCreateInfo->pBindings[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
                     (pCreateInfo->pBindings[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC))) {
                    skip |=
                        LogError("VUID-VkDescriptorSetLayoutCreateInfo-flags-08000", device, binding_loc.dot(Field::descriptorType),
                                 "is %s, but flags includes VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR.",
                                 string_VkDescriptorType(pCreateInfo->pBindings[i].descriptorType));
                }
            }
        }

        if (mutable_descriptor_type) {
            skip |= ValidateMutableDescriptorTypeCreateInfo(*pCreateInfo, *mutable_descriptor_type, create_info_loc);
        }
    }

    // TODO - Remove these 2 extension checks once the enum-to-extensions logic is generated
    // mostly likely will fail test trying to hit these
    if (pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR &&
        !IsExtEnabled(device_extensions.vk_khr_push_descriptor)) {
        skip |= LogError(
            device, kVUID_Core_DrawState_ExtensionNotEnabled,
            "vkCreateDescriptorSetLayout(): Attempted to use %s in %s but its required extension %s has not been enabled.\n",
            "VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR", "VkDescriptorSetLayoutCreateInfo::flags",
            VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
    }
    if (pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT &&
        !IsExtEnabled(device_extensions.vk_ext_descriptor_indexing)) {
        skip |= LogError(
            device, kVUID_Core_DrawState_ExtensionNotEnabled,
            "vkCreateDescriptorSetLayout(): Attemped to use %s in %s but its required extension %s has not been enabled.\n",
            "VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT", "VkDescriptorSetLayoutCreateInfo::flags",
            VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
    }

    if ((pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR) &&
        (pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_EXT)) {
        skip |= LogError("VUID-VkDescriptorSetLayoutCreateInfo-flags-04590", device, create_info_loc.dot(Field::flags), "is %s.",
                         string_VkDescriptorSetLayoutCreateFlags(pCreateInfo->flags).c_str());
    }
    if ((pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT) &&
        (pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_EXT)) {
        skip |= LogError("VUID-VkDescriptorSetLayoutCreateInfo-flags-04592", device, create_info_loc.dot(Field::flags), "is %s.",
                         string_VkDescriptorSetLayoutCreateFlags(pCreateInfo->flags).c_str());
    }
    if (pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_EXT && !mutable_descriptor_type_features_enabled) {
        skip |= LogError("VUID-VkDescriptorSetLayoutCreateInfo-flags-04596", device, create_info_loc.dot(Field::flags),
                         "is %s, but mutableDescriptorType feature was not enabled.",
                         string_VkDescriptorSetLayoutCreateFlags(pCreateInfo->flags).c_str());
    }

    if ((pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_EMBEDDED_IMMUTABLE_SAMPLERS_BIT_EXT) &&
        !(pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT)) {
        skip |= LogError("VUID-VkDescriptorSetLayoutCreateInfo-flags-08001", device, create_info_loc.dot(Field::flags), "is %s.",
                         string_VkDescriptorSetLayoutCreateFlags(pCreateInfo->flags).c_str());
    }

    if ((pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT) &&
        (pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT)) {
        skip |= LogError("VUID-VkDescriptorSetLayoutCreateInfo-flags-08002", device, create_info_loc.dot(Field::flags), "is %s.",
                         string_VkDescriptorSetLayoutCreateFlags(pCreateInfo->flags).c_str());
    }

    if ((pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT) &&
        (pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_VALVE)) {
        skip |= LogError("VUID-VkDescriptorSetLayoutCreateInfo-flags-08003", device, create_info_loc.dot(Field::flags), "is %s.",
                         string_VkDescriptorSetLayoutCreateFlags(pCreateInfo->flags).c_str());
    }

    return skip;
}

bool StatelessValidation::manual_PreCallValidateFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool,
                                                                   uint32_t descriptorSetCount,
                                                                   const VkDescriptorSet *pDescriptorSets,
                                                                   const ErrorObject &error_obj) const {
    // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
    // This is an array of handles, where the elements are allowed to be VK_NULL_HANDLE, and does not require any validation beyond
    // ValidateArray()
    return ValidateArray(error_obj.location.dot(Field::descriptorSetCount), error_obj.location.dot(Field::pDescriptorSets),
                         descriptorSetCount, &pDescriptorSets, true, true, kVUIDUndefined,
                         "VUID-vkFreeDescriptorSets-pDescriptorSets-00310");
}

bool StatelessValidation::ValidateWriteDescriptorSet(const Location &loc, const uint32_t descriptorWriteCount,
                                                     const VkWriteDescriptorSet *pDescriptorWrites,
                                                     const bool isPushDescriptor) const {
    bool skip = false;
    if (!pDescriptorWrites) {
        return skip;
    }
    const char *vkCallingFunction = loc.StringFunc();
    for (uint32_t i = 0; i < descriptorWriteCount; ++i) {
        // descriptorCount must be greater than 0
        if (pDescriptorWrites[i].descriptorCount == 0) {
            skip |= LogError(device, "VUID-VkWriteDescriptorSet-descriptorCount-arraylength",
                             "%s(): parameter pDescriptorWrites[%" PRIu32 "].descriptorCount must be greater than 0.",
                             vkCallingFunction, i);
        }

        // If called from vkCmdPushDescriptorSetKHR, the dstSet member is ignored.
        if (!isPushDescriptor) {
            // dstSet must be a valid VkDescriptorSet handle
            skip |= ValidateRequiredHandle(loc.dot(Field::pDescriptorWrites, i).dot(Field::dstSet), pDescriptorWrites[i].dstSet);
        }

        if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) ||
            (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
            (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
            (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
            (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
            if (pDescriptorWrites[i].pImageInfo == nullptr) {
                if (!isPushDescriptor) {
                    // If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
                    // VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or
                    // VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, pImageInfo must be a pointer to an array of descriptorCount valid
                    // VkDescriptorImageInfo structures. Valid imageView handles are checked in
                    // ObjectLifetimes::ValidateDescriptorWrite.
                    skip |=
                        LogError(device, "VUID-vkUpdateDescriptorSets-pDescriptorWrites-06493",
                                 "%s(): if pDescriptorWrites[%" PRIu32
                                 "].descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "
                                 "VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or "
                                 "VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, pDescriptorWrites[%" PRIu32 "].pImageInfo must not be NULL.",
                                 vkCallingFunction, i, i);
                } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
                           (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
                           (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
                    // If called from vkCmdPushDescriptorSetKHR, pImageInfo is only requred for descriptor types
                    // VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, and
                    // VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT
                    skip |= LogError(device, "VUID-vkCmdPushDescriptorSetKHR-pDescriptorWrites-06494",
                                     "%s(): if pDescriptorWrites[%" PRIu32
                                     "].descriptorType is VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE "
                                     "or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, pDescriptorWrites[%" PRIu32
                                     "].pImageInfo must not be NULL.",
                                     vkCallingFunction, i, i);
                }
            } else if (pDescriptorWrites[i].descriptorType != VK_DESCRIPTOR_TYPE_SAMPLER) {
                // If descriptorType is VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
                // VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, the imageLayout
                // member of any given element of pImageInfo must be a valid VkImageLayout
                for (uint32_t descriptor_index = 0; descriptor_index < pDescriptorWrites[i].descriptorCount; ++descriptor_index) {
                    skip |= ValidateRangedEnum(
                        loc.dot(Field::pDescriptorWrites, i).dot(Field::pImageInfo, descriptor_index).dot(Field::imageLayout),
                        "VkImageLayout", pDescriptorWrites[i].pImageInfo[descriptor_index].imageLayout, kVUIDUndefined);
                }
            }
        } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
                   (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
                   (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
                   (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
            // If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
            // VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, pBufferInfo must be a
            // pointer to an array of descriptorCount valid VkDescriptorBufferInfo structures
            // Valid buffer handles are checked in ObjectLifetimes::ValidateDescriptorWrite.
            if (pDescriptorWrites[i].pBufferInfo == nullptr) {
                skip |= LogError(device, "VUID-VkWriteDescriptorSet-descriptorType-00324",
                                 "%s(): if pDescriptorWrites[%" PRIu32
                                 "].descriptorType is "
                                 "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, "
                                 "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, "
                                 "pDescriptorWrites[%" PRIu32 "].pBufferInfo must not be NULL.",
                                 vkCallingFunction, i, i);
            } else {
                const auto *robustness2_features = vku::FindStructInPNextChain<VkPhysicalDeviceRobustness2FeaturesEXT>(device_createinfo_pnext);
                if (robustness2_features && robustness2_features->nullDescriptor) {
                    for (uint32_t descriptor_index = 0; descriptor_index < pDescriptorWrites[i].descriptorCount;
                         ++descriptor_index) {
                        if (pDescriptorWrites[i].pBufferInfo[descriptor_index].buffer == VK_NULL_HANDLE &&
                            (pDescriptorWrites[i].pBufferInfo[descriptor_index].offset != 0 ||
                             pDescriptorWrites[i].pBufferInfo[descriptor_index].range != VK_WHOLE_SIZE)) {
                            skip |= LogError(device, "VUID-VkDescriptorBufferInfo-buffer-02999",
                                             "%s(): if pDescriptorWrites[%" PRIu32
                                             "].buffer is VK_NULL_HANDLE, "
                                             "offset (%" PRIu64 ") must be zero and range (%" PRIu64 ") must be VK_WHOLE_SIZE.",
                                             vkCallingFunction, i, pDescriptorWrites[i].pBufferInfo[descriptor_index].offset,
                                             pDescriptorWrites[i].pBufferInfo[descriptor_index].range);
                        }
                    }
                }
            }
        } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) ||
                   (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
            // Valid bufferView handles are checked in ObjectLifetimes::ValidateDescriptorWrite.
        }

        if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
            (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)) {
            VkDeviceSize uniform_alignment = device_limits.minUniformBufferOffsetAlignment;
            for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) {
                if (pDescriptorWrites[i].pBufferInfo != NULL) {
                    if (SafeModulo(pDescriptorWrites[i].pBufferInfo[j].offset, uniform_alignment) != 0) {
                        skip |= LogError(device, "VUID-VkWriteDescriptorSet-descriptorType-00327",
                                         "%s(): pDescriptorWrites[%" PRIu32 "].pBufferInfo[%" PRIu32 "].offset (%" PRIu64
                                         ") must be a multiple of device limit minUniformBufferOffsetAlignment %" PRIu64 ".",
                                         vkCallingFunction, i, j, pDescriptorWrites[i].pBufferInfo[j].offset, uniform_alignment);
                    }
                }
            }
        } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
                   (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
            VkDeviceSize storage_alignment = device_limits.minStorageBufferOffsetAlignment;
            for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) {
                if (pDescriptorWrites[i].pBufferInfo != NULL) {
                    if (SafeModulo(pDescriptorWrites[i].pBufferInfo[j].offset, storage_alignment) != 0) {
                        skip |= LogError(device, "VUID-VkWriteDescriptorSet-descriptorType-00328",
                                         "%s(): pDescriptorWrites[%" PRIu32 "].pBufferInfo[%" PRIu32 "].offset (%" PRIu64
                                         ") must be a multiple of device limit minStorageBufferOffsetAlignment %" PRIu64 ".",
                                         vkCallingFunction, i, j, pDescriptorWrites[i].pBufferInfo[j].offset, storage_alignment);
                    }
                }
            }
        }
        // pNext chain must be either NULL or a pointer to a valid instance of VkWriteDescriptorSetAccelerationStructureKHR
        // or VkWriteDescriptorSetInlineUniformBlockEX
        if (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR) {
            const auto *pnext_struct = vku::FindStructInPNextChain<VkWriteDescriptorSetAccelerationStructureKHR>(pDescriptorWrites[i].pNext);
            if (!pnext_struct || (pnext_struct->accelerationStructureCount != pDescriptorWrites[i].descriptorCount)) {
                skip |= LogError(device, "VUID-VkWriteDescriptorSet-descriptorType-02382",
                                 "%s(): If descriptorType is VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, the pNext"
                                 "chain must include a VkWriteDescriptorSetAccelerationStructureKHR structure whose "
                                 "accelerationStructureCount %" PRIu32 " member equals descriptorCount %" PRIu32 ".",
                                 vkCallingFunction, pnext_struct ? pnext_struct->accelerationStructureCount : -1,
                                 pDescriptorWrites[i].descriptorCount);
            }
            // further checks only if we have right structtype
            if (pnext_struct) {
                if (pnext_struct->accelerationStructureCount != pDescriptorWrites[i].descriptorCount) {
                    skip |=
                        LogError(device, "VUID-VkWriteDescriptorSetAccelerationStructureKHR-accelerationStructureCount-02236",
                                 "%s(): accelerationStructureCount %" PRIu32 " must be equal to descriptorCount %" PRIu32
                                 " in the extended structure "
                                 ".",
                                 vkCallingFunction, pnext_struct->accelerationStructureCount, pDescriptorWrites[i].descriptorCount);
                }
                if (pnext_struct->accelerationStructureCount == 0) {
                    skip |=
                        LogError(device, "VUID-VkWriteDescriptorSetAccelerationStructureKHR-accelerationStructureCount-arraylength",
                                 "%s(): accelerationStructureCount must be greater than 0 .", vkCallingFunction);
                }
                const auto *robustness2_features = vku::FindStructInPNextChain<VkPhysicalDeviceRobustness2FeaturesEXT>(device_createinfo_pnext);
                if (robustness2_features && robustness2_features->nullDescriptor == VK_FALSE) {
                    for (uint32_t j = 0; j < pnext_struct->accelerationStructureCount; ++j) {
                        if (pnext_struct->pAccelerationStructures[j] == VK_NULL_HANDLE) {
                            skip |=
                                LogError(device, "VUID-VkWriteDescriptorSetAccelerationStructureKHR-pAccelerationStructures-03580",
                                         "%s(): If the nullDescriptor feature is not enabled, each member of "
                                         "pAccelerationStructures must not be VK_NULL_HANDLE.",
                                         vkCallingFunction);
                        }
                    }
                }
            }
        } else if (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV) {
            const auto *pnext_struct = vku::FindStructInPNextChain<VkWriteDescriptorSetAccelerationStructureNV>(pDescriptorWrites[i].pNext);
            if (!pnext_struct || (pnext_struct->accelerationStructureCount != pDescriptorWrites[i].descriptorCount)) {
                skip |= LogError(device, "VUID-VkWriteDescriptorSet-descriptorType-03817",
                                 "%s(): If descriptorType is VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV, the pNext"
                                 "chain must include a VkWriteDescriptorSetAccelerationStructureNV structure whose "
                                 "accelerationStructureCount %" PRIu32 " member equals descriptorCount %" PRIu32 ".",
                                 vkCallingFunction, pnext_struct ? pnext_struct->accelerationStructureCount : -1,
                                 pDescriptorWrites[i].descriptorCount);
            }
            // further checks only if we have right structtype
            if (pnext_struct) {
                if (pnext_struct->accelerationStructureCount != pDescriptorWrites[i].descriptorCount) {
                    skip |=
                        LogError(device, "VUID-VkWriteDescriptorSetAccelerationStructureNV-accelerationStructureCount-03747",
                                 "%s(): accelerationStructureCount %" PRIu32 " must be equal to descriptorCount %" PRIu32
                                 " in the extended structure "
                                 ".",
                                 vkCallingFunction, pnext_struct->accelerationStructureCount, pDescriptorWrites[i].descriptorCount);
                }
                if (pnext_struct->accelerationStructureCount == 0) {
                    skip |=
                        LogError(device, "VUID-VkWriteDescriptorSetAccelerationStructureNV-accelerationStructureCount-arraylength",
                                 "%s(): accelerationStructureCount must be greater than 0 .", vkCallingFunction);
                }
                const auto *robustness2_features = vku::FindStructInPNextChain<VkPhysicalDeviceRobustness2FeaturesEXT>(device_createinfo_pnext);
                if (robustness2_features && robustness2_features->nullDescriptor == VK_FALSE) {
                    for (uint32_t j = 0; j < pnext_struct->accelerationStructureCount; ++j) {
                        if (pnext_struct->pAccelerationStructures[j] == VK_NULL_HANDLE) {
                            skip |=
                                LogError(device, "VUID-VkWriteDescriptorSetAccelerationStructureNV-pAccelerationStructures-03749",
                                         "%s(): If the nullDescriptor feature is not enabled, each member of "
                                         "pAccelerationStructures must not be VK_NULL_HANDLE.",
                                         vkCallingFunction);
                        }
                    }
                }
            }
        }
    }
    return skip;
}

bool StatelessValidation::manual_PreCallValidateUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
                                                                     const VkWriteDescriptorSet *pDescriptorWrites,
                                                                     uint32_t descriptorCopyCount,
                                                                     const VkCopyDescriptorSet *pDescriptorCopies,
                                                                     const ErrorObject &error_obj) const {
    return ValidateWriteDescriptorSet(error_obj.location, descriptorWriteCount, pDescriptorWrites, false);
}

static bool MutableDescriptorTypePartialOverlap(const VkDescriptorPoolCreateInfo *pCreateInfo, uint32_t i, uint32_t j) {
    bool partial_overlap = false;

    constexpr std::array all_descriptor_types = {
        VK_DESCRIPTOR_TYPE_SAMPLER,
        VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
        VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
        VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
        VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
        VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
        VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
        VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
        VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
        VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
        VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
        VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT,
        VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR,
        VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV,
    };

    const auto *mutable_descriptor_type = vku::FindStructInPNextChain<VkMutableDescriptorTypeCreateInfoEXT>(pCreateInfo->pNext);
    if (mutable_descriptor_type) {
        vvl::span<const VkDescriptorType> first_types, second_types;

        if (mutable_descriptor_type->mutableDescriptorTypeListCount > i) {
            const uint32_t descriptorTypeCount = mutable_descriptor_type->pMutableDescriptorTypeLists[i].descriptorTypeCount;
            auto *pDescriptorTypes = mutable_descriptor_type->pMutableDescriptorTypeLists[i].pDescriptorTypes;
            first_types = vvl::make_span(pDescriptorTypes, descriptorTypeCount);
        } else {
            first_types = vvl::make_span(all_descriptor_types.data(), all_descriptor_types.size());
        }

        if (mutable_descriptor_type->mutableDescriptorTypeListCount > j) {
            const uint32_t descriptorTypeCount = mutable_descriptor_type->pMutableDescriptorTypeLists[j].descriptorTypeCount;
            auto *pDescriptorTypes = mutable_descriptor_type->pMutableDescriptorTypeLists[j].pDescriptorTypes;
            second_types = vvl::make_span(pDescriptorTypes, descriptorTypeCount);
        } else {
            second_types = vvl::make_span(all_descriptor_types.data(), all_descriptor_types.size());
        }

        bool complete_overlap = first_types.size() == second_types.size();
        bool disjoint = true;
        for (const auto first_type : first_types) {
            bool found = false;
            for (const auto second_type : second_types) {
                if (first_type == second_type) {
                    found = true;
                    break;
                }
            }
            if (found) {
                disjoint = false;
            } else {
                complete_overlap = false;
            }
            if (!disjoint && !complete_overlap) {
                partial_overlap = true;
                break;
            }
        }
    }

    return partial_overlap;
}

bool StatelessValidation::manual_PreCallValidateCreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo,
                                                                     const VkAllocationCallbacks *pAllocator,
                                                                     VkDescriptorPool *pDescriptorPool,
                                                                     const ErrorObject &error_obj) const {
    bool skip = false;

    if (!pCreateInfo) {
        return skip;
    }
    const Location create_info_loc = error_obj.location.dot(Field::pCreateInfo);
    if (pCreateInfo->maxSets == 0 && ((pCreateInfo->flags & VK_DESCRIPTOR_POOL_CREATE_ALLOW_OVERALLOCATION_SETS_BIT_NV) == 0)) {
        skip |= LogError("VUID-VkDescriptorPoolCreateInfo-descriptorPoolOverallocation-09227", device,
                         create_info_loc.dot(Field::maxSets), "is zero.");
    }

    const auto *mutable_descriptor_type_features =
        vku::FindStructInPNextChain<VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT>(device_createinfo_pnext);
    bool mutable_descriptor_type_enabled =
        mutable_descriptor_type_features && mutable_descriptor_type_features->mutableDescriptorType == VK_TRUE;

    if (pCreateInfo->pPoolSizes) {
        for (uint32_t i = 0; i < pCreateInfo->poolSizeCount; ++i) {
            const Location pool_loc = create_info_loc.dot(Field::pPoolSizes, i);
            if (pCreateInfo->pPoolSizes[i].descriptorCount <= 0) {
                skip |= LogError("VUID-VkDescriptorPoolSize-descriptorCount-00302", device, pool_loc.dot(Field::descriptorCount),
                                 "is zero.");
            }
            if (pCreateInfo->pPoolSizes[i].type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT &&
                (pCreateInfo->pPoolSizes[i].descriptorCount % 4) != 0) {
                skip |= LogError("VUID-VkDescriptorPoolSize-type-02218", device, pool_loc.dot(Field::descriptorCount),
                                 "is %" PRIu32 " (not a multiple of 4), but type is VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT.",
                                 pCreateInfo->pPoolSizes[i].descriptorCount);
            }
            if (pCreateInfo->pPoolSizes[i].type == VK_DESCRIPTOR_TYPE_MUTABLE_EXT && !mutable_descriptor_type_enabled) {
                skip |= LogError("VUID-VkDescriptorPoolCreateInfo-mutableDescriptorType-04608", device, pool_loc.dot(Field::type),
                                 "is VK_DESCRIPTOR_TYPE_MUTABLE_EXT "
                                 ", but mutableDescriptorType feature was not enabled.");
            }
            if (pCreateInfo->pPoolSizes[i].type == VK_DESCRIPTOR_TYPE_MUTABLE_EXT) {
                for (uint32_t j = i + 1; j < pCreateInfo->poolSizeCount; ++j) {
                    if (pCreateInfo->pPoolSizes[j].type == VK_DESCRIPTOR_TYPE_MUTABLE_EXT) {
                        if (MutableDescriptorTypePartialOverlap(pCreateInfo, i, j)) {
                            skip |= LogError("VUID-VkDescriptorPoolCreateInfo-pPoolSizes-04787", device, pool_loc.dot(Field::type),
                                             "and pCreateInfo->pPoolSizes[%" PRIu32
                                             "].type are both VK_DESCRIPTOR_TYPE_MUTABLE_EXT "
                                             " and have sets which partially overlap.",
                                             j);
                        }
                    }
                }
            }
        }
    }

    if (pCreateInfo->flags & VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_EXT && (!mutable_descriptor_type_enabled)) {
        skip |= LogError("VUID-VkDescriptorPoolCreateInfo-flags-04609", device, create_info_loc.dot(Field::flags),
                         "includes VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_EXT, "
                         "but mutableDescriptorType feature was not enabled.");
    }
    if ((pCreateInfo->flags & VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_EXT) &&
        (pCreateInfo->flags & VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT)) {
        skip |= LogError("VUID-VkDescriptorPoolCreateInfo-flags-04607", device, create_info_loc.dot(Field::flags),
                         "includes both "
                         "VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_EXT and VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT");
    }

    return skip;
}

bool StatelessValidation::manual_PreCallValidateCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo,
                                                                const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool,
                                                                const ErrorObject &error_obj) const {
    bool skip = false;

    // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
    if (!pCreateInfo) {
        return skip;
    }
    const Location create_info_loc = error_obj.location.dot(Field::pCreateInfo);
    // If queryType is VK_QUERY_TYPE_PIPELINE_STATISTICS, pipelineStatistics must be a valid combination of
    // VkQueryPipelineStatisticFlagBits values
    if ((pCreateInfo->queryType == VK_QUERY_TYPE_PIPELINE_STATISTICS) && (pCreateInfo->pipelineStatistics != 0) &&
        ((pCreateInfo->pipelineStatistics & (~AllVkQueryPipelineStatisticFlagBits)) != 0)) {
        skip |= LogError("VUID-VkQueryPoolCreateInfo-queryType-00792", device, create_info_loc.dot(Field::queryType),
                         "is VK_QUERY_TYPE_PIPELINE_STATISTICS, but "
                         "pCreateInfo->pipelineStatistics must be a valid combination of VkQueryPipelineStatisticFlagBits "
                         "values.");
    }
    if (pCreateInfo->queryCount == 0) {
        skip |= LogError("VUID-VkQueryPoolCreateInfo-queryCount-02763", device, create_info_loc.dot(Field::queryCount), "is zero.");
    }
    return skip;
}

bool StatelessValidation::manual_PreCallValidateCreateSamplerYcbcrConversion(VkDevice device,
                                                                             const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
                                                                             const VkAllocationCallbacks *pAllocator,
                                                                             VkSamplerYcbcrConversion *pYcbcrConversion,
                                                                             const ErrorObject &error_obj) const {
    bool skip = false;

    // Check samplerYcbcrConversion feature is set
    const auto *ycbcr_features = vku::FindStructInPNextChain<VkPhysicalDeviceSamplerYcbcrConversionFeatures>(device_createinfo_pnext);
    if ((ycbcr_features == nullptr) || (ycbcr_features->samplerYcbcrConversion == VK_FALSE)) {
        const auto *vulkan_11_features = vku::FindStructInPNextChain<VkPhysicalDeviceVulkan11Features>(device_createinfo_pnext);
        if ((vulkan_11_features == nullptr) || (vulkan_11_features->samplerYcbcrConversion == VK_FALSE)) {
            skip |= LogError("VUID-vkCreateSamplerYcbcrConversion-None-01648", device, error_obj.location,
                             "samplerYcbcrConversion feature must be enabled.");
        }
    }

#ifdef VK_USE_PLATFORM_ANDROID_KHR
    const VkExternalFormatANDROID *external_format_android = vku::FindStructInPNextChain<VkExternalFormatANDROID>(pCreateInfo);
    const bool is_external_format = external_format_android != nullptr && external_format_android->externalFormat != 0;
#else
    const bool is_external_format = false;
#endif

    const VkFormat format = pCreateInfo->format;
    const Location create_info_loc = error_obj.location.dot(Field::pCreateInfo);

    // If there is a VkExternalFormatANDROID with externalFormat != 0, the value of components is ignored.
    if (!is_external_format) {
        const VkComponentMapping components = pCreateInfo->components;
        // XChroma Subsampled is same as "the format has a _422 or _420 suffix" from spec
        if (vkuFormatIsXChromaSubsampled(format) == true) {
            if ((components.g != VK_COMPONENT_SWIZZLE_G) && (components.g != VK_COMPONENT_SWIZZLE_IDENTITY)) {
                skip |= LogError("VUID-VkSamplerYcbcrConversionCreateInfo-components-02581", device, create_info_loc,
                                 "When using a XChroma subsampled format (%s) the components.g needs to be VK_COMPONENT_SWIZZLE_G "
                                 "or VK_COMPONENT_SWIZZLE_IDENTITY, but is %s.",
                                 string_VkFormat(format), string_VkComponentSwizzle(components.g));
            }

            if ((components.a != VK_COMPONENT_SWIZZLE_A) && (components.a != VK_COMPONENT_SWIZZLE_IDENTITY) &&
                (components.a != VK_COMPONENT_SWIZZLE_ONE) && (components.a != VK_COMPONENT_SWIZZLE_ZERO)) {
                skip |=
                    LogError("VUID-VkSamplerYcbcrConversionCreateInfo-components-02582", device, create_info_loc,
                             " When using a XChroma subsampled format (%s) the components.a needs to be VK_COMPONENT_SWIZZLE_A or "
                             "VK_COMPONENT_SWIZZLE_IDENTITY or VK_COMPONENT_SWIZZLE_ONE or VK_COMPONENT_SWIZZLE_ZERO, but is %s.",
                             string_VkFormat(format), string_VkComponentSwizzle(components.a));
            }

            if ((components.r != VK_COMPONENT_SWIZZLE_R) && (components.r != VK_COMPONENT_SWIZZLE_IDENTITY) &&
                (components.r != VK_COMPONENT_SWIZZLE_B)) {
                skip |= LogError("VUID-VkSamplerYcbcrConversionCreateInfo-components-02583", device, create_info_loc,
                                 "When using a XChroma subsampled format (%s) the components.r needs to be VK_COMPONENT_SWIZZLE_R "
                                 "or VK_COMPONENT_SWIZZLE_IDENTITY or VK_COMPONENT_SWIZZLE_B, but is %s.",
                                 string_VkFormat(format), string_VkComponentSwizzle(components.r));
            }

            if ((components.b != VK_COMPONENT_SWIZZLE_B) && (components.b != VK_COMPONENT_SWIZZLE_IDENTITY) &&
                (components.b != VK_COMPONENT_SWIZZLE_R)) {
                skip |= LogError("VUID-VkSamplerYcbcrConversionCreateInfo-components-02584", device, create_info_loc,
                                 "When using a XChroma subsampled format (%s) the components.b needs to be VK_COMPONENT_SWIZZLE_B "
                                 "or VK_COMPONENT_SWIZZLE_IDENTITY or VK_COMPONENT_SWIZZLE_R, but is %s.",
                                 string_VkFormat(format), string_VkComponentSwizzle(components.b));
            }

            // If one is identity, both need to be
            const bool r_identity = ((components.r == VK_COMPONENT_SWIZZLE_R) || (components.r == VK_COMPONENT_SWIZZLE_IDENTITY));
            const bool b_identity = ((components.b == VK_COMPONENT_SWIZZLE_B) || (components.b == VK_COMPONENT_SWIZZLE_IDENTITY));
            if ((r_identity != b_identity) && ((r_identity == true) || (b_identity == true))) {
                skip |= LogError("VUID-VkSamplerYcbcrConversionCreateInfo-components-02585", device, create_info_loc,
                                 "When using a XChroma subsampled format (%s) if either the components.r (%s) or components.b (%s) "
                                 "are an identity swizzle, then both need to be an identity swizzle.",
                                 string_VkFormat(format), string_VkComponentSwizzle(components.r),
                                 string_VkComponentSwizzle(components.b));
            }
        }

        if (pCreateInfo->ycbcrModel != VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY) {
            // Checks same VU multiple ways in order to give a more useful error message
            const char *vuid = "VUID-VkSamplerYcbcrConversionCreateInfo-ycbcrModel-01655";
            if ((components.r == VK_COMPONENT_SWIZZLE_ONE) || (components.r == VK_COMPONENT_SWIZZLE_ZERO) ||
                (components.g == VK_COMPONENT_SWIZZLE_ONE) || (components.g == VK_COMPONENT_SWIZZLE_ZERO) ||
                (components.b == VK_COMPONENT_SWIZZLE_ONE) || (components.b == VK_COMPONENT_SWIZZLE_ZERO)) {
                skip |= LogError(
                    vuid, device, create_info_loc,
                    "The ycbcrModel (%s) is not VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY so components.r (%s), "
                    "components.g (%s), nor components.b (%s) can't be VK_COMPONENT_SWIZZLE_ZERO or VK_COMPONENT_SWIZZLE_ONE.",
                    string_VkSamplerYcbcrModelConversion(pCreateInfo->ycbcrModel), string_VkComponentSwizzle(components.r),
                    string_VkComponentSwizzle(components.g), string_VkComponentSwizzle(components.b));
            }

            // "must not correspond to a component which contains zero or one as a consequence of conversion to RGBA"
            // 4 component format = no issue
            // 3 = no [a]
            // 2 = no [b,a]
            // 1 = no [g,b,a]
            // depth/stencil = no [g,b,a] (shouldn't ever occur, but no VU preventing it)
            const uint32_t component_count = (vkuFormatIsDepthOrStencil(format) == true) ? 1 : vkuFormatComponentCount(format);

            if ((component_count < 4) && ((components.r == VK_COMPONENT_SWIZZLE_A) || (components.g == VK_COMPONENT_SWIZZLE_A) ||
                                          (components.b == VK_COMPONENT_SWIZZLE_A))) {
                skip |=
                    LogError(vuid, device, create_info_loc,
                             "The ycbcrModel (%s) is not VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY so components.r (%s), "
                             "components.g (%s), or components.b (%s) can't be VK_COMPONENT_SWIZZLE_A.",
                             string_VkSamplerYcbcrModelConversion(pCreateInfo->ycbcrModel), string_VkComponentSwizzle(components.r),
                             string_VkComponentSwizzle(components.g), string_VkComponentSwizzle(components.b));
            } else if ((component_count < 3) &&
                       ((components.r == VK_COMPONENT_SWIZZLE_B) || (components.g == VK_COMPONENT_SWIZZLE_B) ||
                        (components.b == VK_COMPONENT_SWIZZLE_B) || (components.b == VK_COMPONENT_SWIZZLE_IDENTITY))) {
                skip |=
                    LogError(vuid, device, create_info_loc,
                             "The ycbcrModel (%s) is not VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY so components.r (%s), "
                             "components.g (%s), or components.b (%s) can't be VK_COMPONENT_SWIZZLE_B "
                             "(components.b also can't be VK_COMPONENT_SWIZZLE_IDENTITY).",
                             string_VkSamplerYcbcrModelConversion(pCreateInfo->ycbcrModel), string_VkComponentSwizzle(components.r),
                             string_VkComponentSwizzle(components.g), string_VkComponentSwizzle(components.b));
            } else if ((component_count < 2) &&
                       ((components.r == VK_COMPONENT_SWIZZLE_G) || (components.g == VK_COMPONENT_SWIZZLE_G) ||
                        (components.g == VK_COMPONENT_SWIZZLE_IDENTITY) || (components.b == VK_COMPONENT_SWIZZLE_G))) {
                skip |=
                    LogError(vuid, device, create_info_loc,
                             "The ycbcrModel (%s) is not VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY so components.r (%s), "
                             "components.g (%s), or components.b (%s) can't be VK_COMPONENT_SWIZZLE_G "
                             "(components.g also can't be VK_COMPONENT_SWIZZLE_IDENTITY).",
                             string_VkSamplerYcbcrModelConversion(pCreateInfo->ycbcrModel), string_VkComponentSwizzle(components.r),
                             string_VkComponentSwizzle(components.g), string_VkComponentSwizzle(components.b));
            }
        }
    }

    return skip;
}

bool StatelessValidation::manual_PreCallValidateCreateSamplerYcbcrConversionKHR(
    VkDevice device, const VkSamplerYcbcrConversionCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
    VkSamplerYcbcrConversion *pYcbcrConversion, const ErrorObject &error_obj) const {
    return manual_PreCallValidateCreateSamplerYcbcrConversion(device, pCreateInfo, pAllocator, pYcbcrConversion, error_obj);
}
