/* 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 <vulkan/vulkan_core.h>
#include <cmath>
#include <cstdint>
#include "containers/custom_containers.h"
#include "error_message/logging.h"
#include "stateless/stateless_validation.h"
#include "generated/enum_flag_bits.h"
#include "containers/range.h"
#include "utils/math_utils.h"
#include "utils/vk_api_utils.h"

namespace stateless {
ReadLockGuard Device::ReadLock() const { return ReadLockGuard(validation_object_mutex, std::defer_lock); }
WriteLockGuard Device::WriteLock() { return WriteLockGuard(validation_object_mutex, std::defer_lock); }

bool Device::ValidateCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType,
                                        const Location& loc) const {
    bool skip = false;
    const bool is_2 = loc.function != Func::vkCmdBindIndexBuffer;
    const char* vuid;

    if (buffer == VK_NULL_HANDLE) {
        if (!enabled_features.maintenance6) {
            vuid = is_2 ? "VUID-vkCmdBindIndexBuffer2-None-09493" : "VUID-vkCmdBindIndexBuffer-None-09493";
            skip |= LogError(vuid, commandBuffer, loc.dot(Field::buffer), "is VK_NULL_HANDLE.");
        } else if (offset != 0) {
            vuid = is_2 ? "VUID-vkCmdBindIndexBuffer2-buffer-09494" : "VUID-vkCmdBindIndexBuffer-buffer-09494";
            skip |= LogError(vuid, commandBuffer, loc.dot(Field::buffer), "is VK_NULL_HANDLE but offset is (%" PRIu64 ").", offset);
        }
    }

    if (indexType == VK_INDEX_TYPE_NONE_KHR) {
        vuid = is_2 ? "VUID-vkCmdBindIndexBuffer2-indexType-08786" : "VUID-vkCmdBindIndexBuffer-indexType-08786";
        skip |= LogError(vuid, commandBuffer, loc.dot(Field::indexType), "is VK_INDEX_TYPE_NONE_KHR.");
    }

    if (indexType == VK_INDEX_TYPE_UINT8 && !enabled_features.indexTypeUint8) {
        vuid = is_2 ? "VUID-vkCmdBindIndexBuffer2-indexType-08787" : "VUID-vkCmdBindIndexBuffer-indexType-08787";
        skip |= LogError(vuid, commandBuffer, loc.dot(Field::indexType),
                         "is VK_INDEX_TYPE_UINT8 but indexTypeUint8 feature was not enabled.");
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
                                                      VkIndexType indexType, const Context& context) const {
    return ValidateCmdBindIndexBuffer(commandBuffer, buffer, offset, indexType, context.error_obj.location);
}

bool Device::manual_PreCallValidateCmdBindIndexBuffer2(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
                                                       VkDeviceSize size, VkIndexType indexType, const Context& context) const {
    return ValidateCmdBindIndexBuffer(commandBuffer, buffer, offset, indexType, context.error_obj.location);
}

bool Device::manual_PreCallValidateCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount,
                                                        const VkBuffer* pBuffers, const VkDeviceSize* pOffsets,
                                                        const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;

    if (firstBinding > phys_dev_props.limits.maxVertexInputBindings) {
        skip |= LogError("VUID-vkCmdBindVertexBuffers-firstBinding-00624", commandBuffer, error_obj.location,
                         "firstBinding (%" PRIu32 ") must be less than maxVertexInputBindings (%" PRIu32 ").", firstBinding,
                         phys_dev_props.limits.maxVertexInputBindings);
    } else if ((firstBinding + bindingCount) > phys_dev_props.limits.maxVertexInputBindings) {
        skip |= LogError("VUID-vkCmdBindVertexBuffers-firstBinding-00625", commandBuffer, error_obj.location,
                         "sum of firstBinding (%" PRIu32 ") and bindingCount (%" PRIu32
                         ") must be less than "
                         "maxVertexInputBindings (%" PRIu32 ").",
                         firstBinding, bindingCount, phys_dev_props.limits.maxVertexInputBindings);
    }

    for (uint32_t i = 0; i < bindingCount; ++i) {
        if (pBuffers == nullptr) {
            skip |= LogError("VUID-vkCmdBindVertexBuffers-pBuffers-parameter", commandBuffer,
                             error_obj.location.dot(Field::pBuffers), "is NULL.");
            return skip;
        }
        if (pBuffers[i] == VK_NULL_HANDLE) {
            const Location buffer_loc = error_obj.location.dot(Field::pBuffers, i);
            if (!enabled_features.nullDescriptor) {
                skip |= LogError("VUID-vkCmdBindVertexBuffers-pBuffers-04001", commandBuffer, buffer_loc, "is VK_NULL_HANDLE.");
            } else {
                if (pOffsets[i] != 0) {
                    skip |= LogError("VUID-vkCmdBindVertexBuffers-pBuffers-04002", commandBuffer, buffer_loc,
                                     "is VK_NULL_HANDLE, but pOffsets[%" PRIu32 "] is not 0.", i);
                }
            }
        }
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdBindTransformFeedbackBuffersEXT(VkCommandBuffer commandBuffer, uint32_t firstBinding,
                                                                      uint32_t bindingCount, const VkBuffer* pBuffers,
                                                                      const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes,
                                                                      const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;

    if (!enabled_features.transformFeedback) {
        skip |= LogError("VUID-vkCmdBindTransformFeedbackBuffersEXT-transformFeedback-02355", commandBuffer, error_obj.location,
                         "transformFeedback feature was not enabled.");
    }

    for (uint32_t i = 0; i < bindingCount; ++i) {
        if (!IsIntegerMultipleOf(pOffsets[i], 4)) {
            skip |= LogError("VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02359", commandBuffer,
                             error_obj.location.dot(Field::pOffsets, i), "(%" PRIu64 ") is not a multiple of 4.", pOffsets[i]);
        }
    }

    if (firstBinding >= phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers) {
        skip |= LogError("VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02356", commandBuffer,
                         error_obj.location.dot(Field::firstBinding),
                         "(%" PRIu32
                         ") is greater than or equal to "
                         "maxTransformFeedbackBuffers (%" PRIu32 ").",
                         firstBinding, phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers);
    }

    if (firstBinding + bindingCount > phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers) {
        skip |= LogError("VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02357", commandBuffer,
                         error_obj.location.dot(Field::firstBinding),
                         "(%" PRIu32 ") plus bindingCount (%" PRIu32 ") is greater than maxTransformFeedbackBuffers (%" PRIu32 ").",
                         firstBinding, bindingCount, phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers);
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdBeginTransformFeedbackEXT(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer,
                                                                uint32_t counterBufferCount, const VkBuffer* pCounterBuffers,
                                                                const VkDeviceSize* pCounterBufferOffsets,
                                                                const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;
    if (!enabled_features.transformFeedback) {
        skip |= LogError("VUID-vkCmdBeginTransformFeedbackEXT-transformFeedback-02366", commandBuffer, error_obj.location,
                         "transformFeedback feature was not enabled.");
    }

    if (firstCounterBuffer >= phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers) {
        skip |= LogError("VUID-vkCmdBeginTransformFeedbackEXT-firstCounter-02368", commandBuffer,
                         error_obj.location.dot(Field::firstCounterBuffer),
                         "(%" PRIu32 ") is not less than maxTransformFeedbackBuffers (%" PRIu32 ").", firstCounterBuffer,
                         phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers);
    }

    if (firstCounterBuffer + counterBufferCount > phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers) {
        skip |= LogError(
            "VUID-vkCmdBeginTransformFeedbackEXT-firstCounter-02369", commandBuffer,
            error_obj.location.dot(Field::firstCounterBuffer),
            "(%" PRIu32 ") plus counterBufferCount (%" PRIu32 ") is greater than maxTransformFeedbackBuffers (%" PRIu32 ").",
            firstCounterBuffer, counterBufferCount, phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers);
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdBeginTransformFeedback2EXT(VkCommandBuffer commandBuffer, uint32_t firstCounterRange,
                                                                 uint32_t counterRangeCount,
                                                                 const VkBindTransformFeedbackBuffer2InfoEXT* pCounterInfos,
                                                                 const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;
    if (!enabled_features.transformFeedback) {
        skip |= LogError("VUID-vkCmdBeginTransformFeedback2EXT-transformFeedback-02366", commandBuffer, error_obj.location,
                         "transformFeedback feature was not enabled.");
    } else if (firstCounterRange >= phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers) {
        skip |= LogError("VUID-vkCmdBeginTransformFeedback2EXT-firstCounter-02368", commandBuffer,
                         error_obj.location.dot(Field::firstCounterRange),
                         "(%" PRIu32 ") is not less than maxTransformFeedbackBuffers (%" PRIu32 ").", firstCounterRange,
                         phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers);
    }
    if (firstCounterRange + counterRangeCount > phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers) {
        skip |= LogError(
            "VUID-vkCmdBeginTransformFeedback2EXT-firstCounter-02369", commandBuffer,
            error_obj.location.dot(Field::firstCounterBuffer),
            "(%" PRIu32 ") plus counterRangeCount (%" PRIu32 ") is greater than maxTransformFeedbackBuffers (%" PRIu32 ").",
            firstCounterRange, counterRangeCount, phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers);
    }
    for (uint32_t i = 0; i < counterRangeCount; i++) {
        const Location info_loc = error_obj.location.dot(Field::pCounterInfos, i);

        skip |= context.ValidateDeviceAddressFlags(info_loc.dot(Field::addressFlags), pCounterInfos[i].addressFlags);

        const VkDeviceSize range_size = pCounterInfos[i].addressRange.size;
        if (range_size > 0 && range_size < 4) {
            skip |= LogError("VUID-vkCmdBeginTransformFeedback2EXT-pCounterInfos-13093", commandBuffer,
                             info_loc.dot(Field::addressRange).dot(Field::size), "is %" PRIu64 ".", range_size);
        }
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdEndTransformFeedbackEXT(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer,
                                                              uint32_t counterBufferCount, const VkBuffer* pCounterBuffers,
                                                              const VkDeviceSize* pCounterBufferOffsets,
                                                              const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;
    if (!enabled_features.transformFeedback) {
        skip |= LogError("VUID-vkCmdEndTransformFeedbackEXT-transformFeedback-02374", commandBuffer, error_obj.location,
                         "transformFeedback feature was not enabled.");
    }

    // pCounterBuffers and pCounterBufferOffsets are optional and may be nullptr.
    // Additionally, pCounterBufferOffsets must be nullptr if pCounterBuffers is nullptr.
    if (pCounterBuffers == nullptr && pCounterBufferOffsets != nullptr) {
        skip |= LogError("VUID-vkCmdEndTransformFeedbackEXT-pCounterBuffer-02379", commandBuffer,
                         error_obj.location.dot(Field::pCounterBuffers), "is NULL but pCounterBufferOffsets is not NULL.");
    }

    if (firstCounterBuffer >= phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers) {
        skip |= LogError("VUID-vkCmdEndTransformFeedbackEXT-firstCounterBuffer-02376", commandBuffer,
                         error_obj.location.dot(Field::firstCounterBuffer),
                         "(%" PRIu32 ") is not less than maxTransformFeedbackBuffers (%" PRIu32 ").", firstCounterBuffer,
                         phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers);
    }

    if (firstCounterBuffer + counterBufferCount > phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers) {
        skip |= LogError(
            "VUID-vkCmdEndTransformFeedbackEXT-firstCounterBuffer-02377", commandBuffer,
            error_obj.location.dot(Field::firstCounterBuffer),
            "(%" PRIu32 ") plus counterBufferCount (%" PRIu32 ") is greater than maxTransformFeedbackBuffers (%" PRIu32 ").",
            firstCounterBuffer, counterBufferCount, phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers);
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdBindVertexBuffers2(VkCommandBuffer commandBuffer, uint32_t firstBinding,
                                                         uint32_t bindingCount, const VkBuffer* pBuffers,
                                                         const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes,
                                                         const VkDeviceSize* pStrides, const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;

    // Check VUID-vkCmdBindVertexBuffers2-bindingCount-arraylength
    // This is a special case and generator currently skips it
    {
        const bool vuid_condition = (pSizes != nullptr) || (pStrides != nullptr);
        const bool vuid_expectation = bindingCount > 0;
        if (vuid_condition) {
            if (!vuid_expectation) {
                const char* not_null_msg = "";
                if ((pSizes != nullptr) && (pStrides != nullptr)) {
                    not_null_msg = "pSizes and pStrides are not NULL";
                } else if (pSizes != nullptr) {
                    not_null_msg = "pSizes is not NULL";
                } else {
                    not_null_msg = "pStrides is not NULL";
                }
                skip |= LogError("VUID-vkCmdBindVertexBuffers2-bindingCount-arraylength", commandBuffer, error_obj.location,
                                 "%s, so bindingCount must be greater than 0.", not_null_msg);
            }
        }

        if (!pOffsets && bindingCount > 0) {
            skip |= LogError("VUID-vkCmdBindVertexBuffers2-pOffsets-parameter", commandBuffer,
                             error_obj.location.dot(Field::pOffsets), "is NULL.");
        }
    }

    if (firstBinding >= phys_dev_props.limits.maxVertexInputBindings) {
        skip |=
            LogError("VUID-vkCmdBindVertexBuffers2-firstBinding-03355", commandBuffer, error_obj.location.dot(Field::firstBinding),
                     "(%" PRIu32 ") must be less than maxVertexInputBindings (%" PRIu32 ").", firstBinding,
                     phys_dev_props.limits.maxVertexInputBindings);
    } else if ((firstBinding + bindingCount) > phys_dev_props.limits.maxVertexInputBindings) {
        skip |=
            LogError("VUID-vkCmdBindVertexBuffers2-firstBinding-03356", commandBuffer, error_obj.location.dot(Field::firstBinding),
                     "(%" PRIu32 ") + bindingCount (%" PRIu32
                     ") must be less than "
                     "maxVertexInputBindings (%" PRIu32 ").",
                     firstBinding, bindingCount, phys_dev_props.limits.maxVertexInputBindings);
    }

    for (uint32_t i = 0; i < bindingCount; ++i) {
        if (pBuffers == nullptr) {
            skip |= LogError("VUID-vkCmdBindVertexBuffers2-pBuffers-parameter", commandBuffer,
                             error_obj.location.dot(Field::pBuffers), "is NULL.");
            return skip;
        }
        if (pBuffers[i] == VK_NULL_HANDLE) {
            const Location buffer_loc = error_obj.location.dot(Field::pBuffers, i);
            if (!enabled_features.nullDescriptor) {
                skip |= LogError("VUID-vkCmdBindVertexBuffers2-pBuffers-04111", commandBuffer, buffer_loc, "is VK_NULL_HANDLE.");
            } else if (pOffsets && pOffsets[i] != 0) {
                skip |= LogError("VUID-vkCmdBindVertexBuffers2-pBuffers-04112", commandBuffer, buffer_loc,
                                 "is VK_NULL_HANDLE, but pOffsets[%" PRIu32 "] is not 0.", i);
            }
        }
        if (pStrides) {
            if (pStrides[i] > phys_dev_props.limits.maxVertexInputBindingStride) {
                skip |= LogError("VUID-vkCmdBindVertexBuffers2-pStrides-03362", commandBuffer,
                                 error_obj.location.dot(Field::pStrides, i),
                                 "(%" PRIu64 ") must be less than maxVertexInputBindingStride (%" PRIu32 ").", pStrides[i],
                                 phys_dev_props.limits.maxVertexInputBindingStride);
            }
        }
    }

    return skip;
}

bool Device::ValidateCmdPushConstants(VkCommandBuffer commandBuffer, uint32_t offset, uint32_t size, const Location& loc) const {
    bool skip = false;
    const bool is_2 = loc.function != Func::vkCmdPushConstants;
    const uint32_t max_push_constants_size = phys_dev_props.limits.maxPushConstantsSize;
    // Check that offset + size don't exceed the max.
    // Prevent arithetic overflow here by avoiding addition and testing in this order.
    if (offset >= max_push_constants_size) {
        const char* vuid = is_2 ? "VUID-VkPushConstantsInfo-offset-00370" : "VUID-vkCmdPushConstants-offset-00370";
        skip |= LogError(vuid, commandBuffer, loc.dot(Field::offset),
                         "(%" PRIu32 ") is greater than maxPushConstantSize (%" PRIu32 ").", offset, max_push_constants_size);
    }
    if (size > max_push_constants_size - offset) {
        const char* vuid = is_2 ? "VUID-VkPushConstantsInfo-size-00371" : "VUID-vkCmdPushConstants-size-00371";
        skip |= LogError(vuid, commandBuffer, loc.dot(Field::offset),
                         "(%" PRIu32 ") plus size (%" PRIu32 ") is greater than maxPushConstantSize (%" PRIu32 ").", offset, size,
                         max_push_constants_size);
    }

    if (!IsIntegerMultipleOf(size, 4)) {
        const char* vuid = is_2 ? "VUID-VkPushConstantsInfo-size-00369" : "VUID-vkCmdPushConstants-size-00369";
        skip |= LogError(vuid, commandBuffer, loc.dot(Field::size), "(%" PRIu32 ") must be a multiple of 4.", size);
    }

    if (!IsIntegerMultipleOf(offset, 4)) {
        const char* vuid = is_2 ? "VUID-VkPushConstantsInfo-offset-00368" : "VUID-vkCmdPushConstants-offset-00368";
        skip |= LogError(vuid, commandBuffer, loc.dot(Field::offset), "(%" PRIu32 ") must be a multiple of 4.", offset);
    }
    return skip;
}

bool Device::manual_PreCallValidateCmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout,
                                                    VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size,
                                                    const void* pValues, const Context& context) const {
    return ValidateCmdPushConstants(commandBuffer, offset, size, context.error_obj.location);
}

bool Device::manual_PreCallValidateCmdPushConstants2(VkCommandBuffer commandBuffer, const VkPushConstantsInfo* pPushConstantsInfo,
                                                     const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;
    skip |= ValidateCmdPushConstants(commandBuffer, pPushConstantsInfo->offset, pPushConstantsInfo->size,
                                     error_obj.location.dot(Field::pPushConstantsInfo));
    if (pPushConstantsInfo->layout == VK_NULL_HANDLE) {
        if (!enabled_features.dynamicPipelineLayout) {
            skip |= LogError("VUID-VkPushConstantsInfo-None-09495", commandBuffer,
                             error_obj.location.dot(Field::pPushConstantsInfo).dot(Field::layout), "is VK_NULL_HANDLE.");
        } else if (!vku::FindStructInPNextChain<VkPipelineLayoutCreateInfo>(pPushConstantsInfo->pNext)) {
            skip |= LogError("VUID-VkPushConstantsInfo-layout-09496", commandBuffer,
                             error_obj.location.dot(Field::pPushConstantsInfo).dot(Field::layout),
                             "is VK_NULL_HANDLE and pNext is missing VkPipelineLayoutCreateInfo.");
        }
    }
    return skip;
}

bool Device::manual_PreCallValidateCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout,
                                                      const VkClearColorValue* pColor, uint32_t rangeCount,
                                                      const VkImageSubresourceRange* pRanges, const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;
    if (!pColor) {
        skip |= LogError("VUID-vkCmdClearColorImage-pColor-04961", commandBuffer, error_obj.location, "pColor must not be null");
    }
    return skip;
}

bool Device::manual_PreCallValidateGetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery,
                                                       uint32_t queryCount, size_t dataSize, void* pData, VkDeviceSize stride,
                                                       VkQueryResultFlags flags, const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;

    if ((flags & VK_QUERY_RESULT_WITH_STATUS_BIT_KHR) && (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)) {
        skip |= LogError("VUID-vkGetQueryPoolResults-flags-09443", device, error_obj.location.dot(Field::flags),
                         "(%s) include both STATUS_BIT and AVAILABILITY_BIT.", string_VkQueryResultFlags(flags).c_str());
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdCopyQueryPoolResultsToMemoryKHR(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
                                                                      uint32_t firstQuery, uint32_t queryCount,
                                                                      const VkStridedDeviceAddressRangeKHR* pDstRange,
                                                                      VkAddressCommandFlagsKHR dstFlags,
                                                                      VkQueryResultFlags queryResultFlags,
                                                                      const Context& context) const {
    bool skip = false;

    const auto& error_obj = context.error_obj;
    skip |= context.ValidateDeviceAddressFlags(error_obj.location.dot(Field::dstFlags), dstFlags);

    if (queryCount > 1 && pDstRange->stride == 0) {
        const LogObjectList objlist(commandBuffer, queryPool);
        skip |= LogError("VUID-vkCmdCopyQueryPoolResultsToMemoryKHR-queryCount-09438", objlist,
                         error_obj.location.dot(Field::queryCount), "is %" PRIu32 " but stride is zero.", queryCount);
    }

    if (queryResultFlags & VK_QUERY_RESULT_64_BIT) {
        if (!IsPointerAligned(pDstRange->address, 8) || !IsIntegerMultipleOf(pDstRange->stride, 8)) {
            const LogObjectList objlist(commandBuffer, queryPool);
            skip |= LogError("VUID-vkCmdCopyQueryPoolResultsToMemoryKHR-flags-13078", objlist,
                             error_obj.location.dot(Field::pDstRange).dot(Field::address),
                             "(0x%" PRIx64 ") must be aligned to 8 and pDstRange.stride (%" PRIu64 ") must be a multiple of 8.",
                             pDstRange->address, pDstRange->stride);
        }
    } else {
        if (!IsPointerAligned(pDstRange->address, 4) || !IsIntegerMultipleOf(pDstRange->stride, 4)) {
            const LogObjectList objlist(commandBuffer, queryPool);
            skip |= LogError("VUID-vkCmdCopyQueryPoolResultsToMemoryKHR-flags-13077", objlist,
                             error_obj.location.dot(Field::pDstRange).dot(Field::address),
                             "(0x%" PRIx64 ") must be aligned to 4 and pDstRange.stride (%" PRIu64 ") must be a multiple of 4.",
                             pDstRange->address, pDstRange->stride);
        }
    }

    if ((queryResultFlags & VK_QUERY_RESULT_WITH_STATUS_BIT_KHR) && (queryResultFlags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)) {
        const LogObjectList objlist(commandBuffer, queryPool);
        skip |= LogError("VUID-vkCmdCopyQueryPoolResultsToMemoryKHR-flags-09443", objlist,
                         error_obj.location.dot(Field::queryResultFlags),
                         "(%s) includes both VK_QUERY_RESULT_WITH_STATUS_BIT_KHR and VK_QUERY_RESULT_WITH_AVAILABILITY_BIT.",
                         string_VkQueryResultFlags(queryResultFlags).c_str());
    }

    if (dstFlags & VK_ADDRESS_COMMAND_PROTECTED_BIT_KHR) {
        const LogObjectList objlist(commandBuffer, queryPool);
        skip |= LogError("VUID-vkCmdCopyQueryPoolResultsToMemoryKHR-dstFlags-13085", objlist,
                         error_obj.location.dot(Field::dstFlags), "(%s) must not contain VK_ADDRESS_COMMAND_PROTECTED_BIT_KHR.",
                         string_VkAddressCommandFlagsKHR(dstFlags).c_str());
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdBeginConditionalRenderingEXT(
    VkCommandBuffer commandBuffer, const VkConditionalRenderingBeginInfoEXT* pConditionalRenderingBegin,
    const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;

    if (!IsIntegerMultipleOf(pConditionalRenderingBegin->offset, 4)) {
        skip |= LogError("VUID-VkConditionalRenderingBeginInfoEXT-offset-01984", commandBuffer,
                         error_obj.location.dot(Field::pConditionalRenderingBegin).dot(Field::offset),
                         "(%" PRIu64 ") is not a multiple of 4.", pConditionalRenderingBegin->offset);
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount,
                                                       const VkClearAttachment* pAttachments, uint32_t rectCount,
                                                       const VkClearRect* pRects, const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;
    for (uint32_t rect = 0; rect < rectCount; rect++) {
        const VkClearRect& clear_rect = pRects[rect];
        const Location rect_loc = error_obj.location.dot(Field::pRects, rect);
        if (clear_rect.layerCount == 0) {
            skip |=
                LogError("VUID-vkCmdClearAttachments-layerCount-01934", commandBuffer, rect_loc.dot(Field::layerCount), "is zero.");
        }
        if (clear_rect.rect.extent.width == 0) {
            skip |= LogError("VUID-vkCmdClearAttachments-rect-02682", commandBuffer,
                             rect_loc.dot(Field::rect).dot(Field::extent).dot(Field::width), "is zero.");
        }
        if (clear_rect.rect.extent.height == 0) {
            skip |= LogError("VUID-vkCmdClearAttachments-rect-02683", commandBuffer,
                             rect_loc.dot(Field::rect).dot(Field::extent).dot(Field::height), "is zero.");
        }
    }
    return skip;
}

bool Device::manual_PreCallValidateCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer,
                                                 uint32_t regionCount, const VkBufferCopy* pRegions, const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;

    if (pRegions != nullptr) {
        for (uint32_t i = 0; i < regionCount; i++) {
            if (pRegions[i].size == 0) {
                skip |= LogError("VUID-VkBufferCopy-size-01988", commandBuffer,
                                 error_obj.location.dot(Field::pRegions, i).dot(Field::size), "is zero");
            }
        }
    }
    return skip;
}

bool Device::manual_PreCallValidateCmdCopyBuffer2(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2* pCopyBufferInfo,
                                                  const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;

    if (pCopyBufferInfo->pRegions != nullptr) {
        for (uint32_t i = 0; i < pCopyBufferInfo->regionCount; i++) {
            if (pCopyBufferInfo->pRegions[i].size == 0) {
                skip |=
                    LogError("VUID-VkBufferCopy2-size-01988", commandBuffer,
                             error_obj.location.dot(Field::pCopyBufferInfo).dot(Field::pRegions, i).dot(Field::size), "is zero");
            }
        }
    }
    return skip;
}

bool Device::manual_PreCallValidateCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset,
                                                   VkDeviceSize dataSize, const void* pData, const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;

    if (!IsIntegerMultipleOf(dstOffset, 4)) {
        const LogObjectList objlist(commandBuffer, dstBuffer);
        skip |= LogError("VUID-vkCmdUpdateBuffer-dstOffset-00036", objlist, error_obj.location.dot(Field::dstOffset),
                         "(%" PRIu64 ") is not a multiple of 4.", dstOffset);
    }

    if ((dataSize <= 0) || (dataSize > 65536)) {
        const LogObjectList objlist(commandBuffer, dstBuffer);
        skip |= LogError("VUID-vkCmdUpdateBuffer-dataSize-00037", objlist, error_obj.location.dot(Field::dataSize),
                         "(%" PRIu64 ") must be greater than zero and less than or equal to 65536.", dataSize);
    } else if (!IsIntegerMultipleOf(dataSize, 4)) {
        const LogObjectList objlist(commandBuffer, dstBuffer);
        skip |= LogError("VUID-vkCmdUpdateBuffer-dataSize-00038", objlist, error_obj.location.dot(Field::dataSize),
                         "(%" PRIu64 ") is not a multiple of 4.", dataSize);
    }
    return skip;
}

bool Device::manual_PreCallValidateCmdUpdateMemoryKHR(VkCommandBuffer commandBuffer, const VkDeviceAddressRangeKHR* pDstRange,
                                                      VkAddressCommandFlagsKHR dstFlags, VkDeviceSize dataSize, const void* pData,
                                                      const Context& context) const {
    bool skip = false;

    const auto& error_obj = context.error_obj;
    skip |= context.ValidateDeviceAddressFlags(error_obj.location.dot(Field::dstFlags), dstFlags);

    if (!IsPointerAligned(pDstRange->address, 4)) {
        skip |= LogError("VUID-vkCmdUpdateMemoryKHR-pDstRange-13006", commandBuffer,
                         error_obj.location.dot(Field::pDstRange).dot(Field::address),
                         "(0x%" PRIx64 ") must be aligned to 4 bytes.", pDstRange->address);
    }
    if (pDstRange->size > 65536) {
        skip |= LogError("VUID-vkCmdUpdateMemoryKHR-pDstRange-13007", commandBuffer,
                         error_obj.location.dot(Field::pDstRange).dot(Field::size), "(%" PRIu64 ") is greater than 65536.",
                         pDstRange->size);
    }
    if (dataSize > pDstRange->size) {
        skip |= LogError("VUID-vkCmdUpdateMemoryKHR-dataSize-13008", commandBuffer, error_obj.location.dot(Field::dataSize),
                         "(%" PRIu64 ") is greater than pDstRange->size (%" PRIu64 ").", dataSize, pDstRange->size);
    }
    if (!IsIntegerMultipleOf(dataSize, 4)) {
        skip |= LogError("VUID-vkCmdUpdateMemoryKHR-dataSize-13009", commandBuffer, error_obj.location.dot(Field::dataSize),
                         "(%" PRIu64 ") is not a multiple of 4.", dataSize);
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdCopyMemoryToImageKHR(VkCommandBuffer commandBuffer,
                                                           const VkCopyDeviceMemoryImageInfoKHR* pCopyMemoryInfo,
                                                           const Context& context) const {
    bool skip = false;

    const auto& error_obj = context.error_obj;
    for (uint32_t i = 0; i < pCopyMemoryInfo->regionCount; i++) {
        const VkDeviceMemoryImageCopyKHR& region = pCopyMemoryInfo->pRegions[i];
        skip |= context.ValidateDeviceAddressFlags(error_obj.location.dot(Field::pRegions, i).dot(Field::addressFlags),
                                                   region.addressFlags);
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdCopyImageToMemoryKHR(VkCommandBuffer commandBuffer,
                                                           const VkCopyDeviceMemoryImageInfoKHR* pCopyMemoryInfo,
                                                           const Context& context) const {
    bool skip = false;

    for (uint32_t i = 0; i < pCopyMemoryInfo->regionCount; i++) {
        const VkDeviceMemoryImageCopyKHR& region = pCopyMemoryInfo->pRegions[i];
        const Location loc = context.error_obj.location.dot(Field::pRegions, i);
        skip |= context.ValidateDeviceAddressFlags(loc.dot(Field::addressFlags), region.addressFlags);
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdCopyMemoryKHR(VkCommandBuffer commandBuffer, const VkCopyDeviceMemoryInfoKHR* pCopyMemoryInfo,
                                                    const Context& context) const {
    bool skip = false;

    for (uint32_t i = 0; i < pCopyMemoryInfo->regionCount; i++) {
        const VkDeviceMemoryCopyKHR& region = pCopyMemoryInfo->pRegions[i];
        const Location region_loc = context.error_obj.location.dot(Field::pRegions, i);
        skip |= context.ValidateDeviceAddressFlags(region_loc.dot(Field::dstFlags), region.dstFlags);
        skip |= context.ValidateDeviceAddressFlags(region_loc.dot(Field::srcFlags), region.srcFlags);

        if (region.dstRange.size < region.srcRange.size) {
            skip |=
                LogError("VUID-VkDeviceMemoryCopyKHR-size-13016", commandBuffer, region_loc.dot(Field::dstRange).dot(Field::size),
                         "(%" PRIu64 ") is less than srcRange.size (%" PRIu64 ").", region.dstRange.size, region.srcRange.size);
        }

        vvl::range<VkDeviceAddress> region_src_range = {region.srcRange.address, region.srcRange.address + region.srcRange.size};
        for (uint32_t j = i; j < pCopyMemoryInfo->regionCount; ++j) {
            const VkDeviceMemoryCopyKHR& other_region = pCopyMemoryInfo->pRegions[j];
            vvl::range<VkDeviceAddress> next_src_range = {other_region.srcRange.address,
                                                          other_region.srcRange.address + other_region.srcRange.size};
            vvl::range<VkDeviceAddress> next_dst_range = {other_region.dstRange.address,
                                                          other_region.dstRange.address + other_region.dstRange.size};

            // j > i so that the current src range is not compared to itself
            if (j > i && region_src_range.intersects(next_src_range)) {
                skip |= LogError("VUID-VkCopyDeviceMemoryInfoKHR-srcRange-13015", commandBuffer, region_loc.dot(Field::srcRange),
                                 "%s overlaps with pRegions[%" PRIu32 "].srcRange %s", string_range_hex(region_src_range).c_str(),
                                 j, string_range_hex(next_src_range).c_str());
            } else if (region_src_range.intersects(next_dst_range)) {
                skip |= LogError("VUID-VkCopyDeviceMemoryInfoKHR-srcRange-13015", commandBuffer, region_loc.dot(Field::srcRange),
                                 "%s overlaps with pRegions[%" PRIu32 "].dstRange %s", string_range_hex(region_src_range).c_str(),
                                 j, string_range_hex(next_dst_range).c_str());
            }
        }
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdBeginConditionalRendering2EXT(
    VkCommandBuffer commandBuffer, const VkConditionalRenderingBeginInfo2EXT* pConditionalRenderingBegin,
    const Context& context) const {
    bool skip = false;

    const auto& error_obj = context.error_obj;
    skip |= context.ValidateDeviceAddressFlags(error_obj.location.dot(Field::pConditionalRenderingBegin).dot(Field::addressFlags),
                                               pConditionalRenderingBegin->addressFlags);

    if (!IsPointerAligned(pConditionalRenderingBegin->addressRange.address, 4)) {
        skip |= LogError("VUID-VkConditionalRenderingBeginInfo2EXT-addressRange-13065", commandBuffer,
                         error_obj.location.dot(Field::pConditionalRenderingBegin).dot(Field::addressRange).dot(Field::address),
                         "(0x%" PRIx64 ") must be aligned to 4 bytes.", pConditionalRenderingBegin->addressRange.address);
    }

    if (pConditionalRenderingBegin->addressRange.size < 4) {
        skip |= LogError("VUID-VkConditionalRenderingBeginInfo2EXT-addressRange-13066", commandBuffer,
                         error_obj.location.dot(Field::pConditionalRenderingBegin).dot(Field::addressRange).dot(Field::size),
                         "(%" PRIu64 ") is less than 4.", pConditionalRenderingBegin->addressRange.size);
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdBindVertexBuffers3KHR(VkCommandBuffer commandBuffer, uint32_t firstBinding,
                                                            uint32_t bindingCount, const VkBindVertexBuffer3InfoKHR* pBindingInfos,
                                                            const Context& context) const {
    bool skip = false;

    const auto& error_obj = context.error_obj;

    if (firstBinding >= phys_dev_props.limits.maxVertexInputBindings) {
        skip |= LogError("VUID-vkCmdBindVertexBuffers3KHR-firstBinding-13070", commandBuffer,
                         error_obj.location.dot(Field::firstBinding),
                         "(%" PRIu32 ") is not less than maxVertexInputBindings (%" PRIu32 ").", firstBinding,
                         phys_dev_props.limits.maxVertexInputBindings);
    } else if (firstBinding + bindingCount > phys_dev_props.limits.maxVertexInputBindings) {
        skip |= LogError("VUID-vkCmdBindVertexBuffers3KHR-firstBinding-13071", commandBuffer,
                         error_obj.location.dot(Field::firstBinding),
                         "(%" PRIu32 ") + bindingCount (%" PRIu32 ") is greater than maxVertexInputBindings (%" PRIu32 ").",
                         firstBinding, bindingCount, phys_dev_props.limits.maxVertexInputBindings);
    }
    for (uint32_t i = 0; i < bindingCount; ++i) {
        const Location binding_info_loc = error_obj.location.dot(Field::pBindingInfos, i);
        const VkBindVertexBuffer3InfoKHR& info = pBindingInfos[i];
        const VkStridedDeviceAddressRangeKHR& address_range = info.addressRange;

        skip |= context.ValidateDeviceAddressFlags(binding_info_loc.dot(Field::addressFlags), info.addressFlags);

        if (address_range.size == 0) {
            if (!enabled_features.nullDescriptor) {
                skip |= LogError("VUID-VkBindVertexBuffer3InfoKHR-size-13072", commandBuffer,
                                 binding_info_loc.dot(Field::addressRange).dot(Field::size),
                                 "is 0, but the nullDescriptor feature is not enabled.");
            } else if (address_range.address != 0) {
                skip |= LogError("VUID-VkBindVertexBuffer3InfoKHR-addressRange-13075", commandBuffer,
                                 binding_info_loc.dot(Field::addressRange).dot(Field::size),
                                 "is 0, but addressRange.address (0x%" PRIx64 ") must be zero.", info.addressRange.address);
            }
        }

        if (info.setStride == VK_TRUE) {
            if (info.addressRange.stride > phys_dev_props.limits.maxVertexInputBindingStride) {
                skip |= LogError("VUID-VkBindVertexBuffer3InfoKHR-setStride-13126", commandBuffer,
                                 binding_info_loc.dot(Field::addressRange).dot(Field::stride),
                                 "(%" PRIu64 ") is greater than maxVertexInputBindingStride (%" PRIu32 ").",
                                 info.addressRange.stride, phys_dev_props.limits.maxVertexInputBindingStride);
            }
        } else {
            if (info.addressRange.stride != 0) {
                skip |= LogError("VUID-VkBindVertexBuffer3InfoKHR-setStride-13127", commandBuffer,
                                 binding_info_loc.dot(Field::addressRange).dot(Field::stride),
                                 "(%" PRIu64 ") is non-zero, but setStride is VK_FALSE.", info.addressRange.stride);
            }
        }
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdBindTransformFeedbackBuffers2EXT(VkCommandBuffer commandBuffer, uint32_t firstBinding,
                                                                       uint32_t bindingCount,
                                                                       const VkBindTransformFeedbackBuffer2InfoEXT* pBindingInfos,
                                                                       const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;

    if (!enabled_features.transformFeedback) {
        skip |= LogError("VUID-vkCmdBindTransformFeedbackBuffers2EXT-transformFeedback-02355", commandBuffer, error_obj.location,
                         "transformFeedback feature was not enabled.");
    } else if (firstBinding >= phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers) {
        skip |= LogError("VUID-vkCmdBindTransformFeedbackBuffers2EXT-firstBinding-02356", commandBuffer,
                         error_obj.location.dot(Field::firstBinding),
                         "(%" PRIu32 ") is greater than or equal to maxTransformFeedbackBuffers (%" PRIu32 ").", firstBinding,
                         phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers);
    } else if (firstBinding + bindingCount > phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers) {
        skip |= LogError("VUID-vkCmdBindTransformFeedbackBuffers2EXT-firstBinding-02357", commandBuffer,
                         error_obj.location.dot(Field::firstBinding),
                         "(%" PRIu32 ") plus bindingCount (%" PRIu32 ") is greater than maxTransformFeedbackBuffers (%" PRIu32 ").",
                         firstBinding, bindingCount, phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers);
    }

    for (uint32_t i = 0; i < bindingCount; i++) {
        const Location info_loc = error_obj.location.dot(Field::pBindingInfos, i);
        const VkBindTransformFeedbackBuffer2InfoEXT& binding_info = pBindingInfos[i];

        skip |= context.ValidateDeviceAddressFlags(info_loc.dot(Field::addressFlags), binding_info.addressFlags);

        const VkDeviceSize range_size = binding_info.addressRange.size;
        if (!IsIntegerMultipleOf(range_size, 4)) {
            skip |= LogError("VUID-vkCmdBindTransformFeedbackBuffers2EXT-addressRange-13090", commandBuffer,
                             info_loc.dot(Field::addressRange).dot(Field::size), "is %" PRIu64 ".", range_size);
        }

        if (binding_info.addressRange.size > phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBufferSize) {
            skip |= LogError("VUID-vkCmdBindTransformFeedbackBuffers2EXT-addressRange-13092", commandBuffer,
                             info_loc.dot(Field::addressRange).dot(Field::size),
                             "(%" PRIu64 ") is greater than maxTransformFeedbackBufferSize (%" PRIu64 ").",
                             binding_info.addressRange.size,
                             phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBufferSize);
        }
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdEndTransformFeedback2EXT(VkCommandBuffer commandBuffer, uint32_t firstCounterRange,
                                                               uint32_t counterRangeCount,
                                                               const VkBindTransformFeedbackBuffer2InfoEXT* pCounterInfos,
                                                               const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;

    if (!enabled_features.transformFeedback) {
        skip |= LogError("VUID-vkCmdEndTransformFeedback2EXT-transformFeedback-02374", commandBuffer, error_obj.location,
                         "transformFeedback feature was not enabled.");
    } else if (firstCounterRange >= phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers) {
        skip |= LogError("VUID-vkCmdEndTransformFeedback2EXT-firstCounterBuffer-02376", commandBuffer,
                         error_obj.location.dot(Field::firstCounterRange),
                         "(%" PRIu32 ") is not less than maxTransformFeedbackBuffers (%" PRIu32 ").", firstCounterRange,
                         phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers);
    } else if (firstCounterRange + counterRangeCount > phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers) {
        skip |= LogError(
            "VUID-vkCmdEndTransformFeedback2EXT-firstCounterBuffer-02377", commandBuffer,
            error_obj.location.dot(Field::firstCounterRange),
            "(%" PRIu32 ") plus counterRangeCount (%" PRIu32 ") is greater than maxTransformFeedbackBuffers (%" PRIu32 ").",
            firstCounterRange, counterRangeCount, phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBuffers);
    }

    for (uint32_t i = 0; i < counterRangeCount; i++) {
        const Location info_loc = error_obj.location.dot(Field::pCounterInfos, i);
        skip |= context.ValidateDeviceAddressFlags(info_loc.dot(Field::addressFlags), pCounterInfos[i].addressFlags);

        const VkDeviceSize range_size = pCounterInfos[i].addressRange.size;
        if (range_size > 0 && range_size < 4) {
            skip |= LogError("VUID-vkCmdEndTransformFeedback2EXT-pCounterInfos-13095", commandBuffer,
                             info_loc.dot(Field::addressRange).dot(Field::size), "is %" PRIu64 ".", range_size);
        }
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdDrawIndirectByteCount2EXT(VkCommandBuffer commandBuffer, uint32_t instanceCount,
                                                                uint32_t firstInstance,
                                                                const VkBindTransformFeedbackBuffer2InfoEXT* pCounterInfo,
                                                                uint32_t counterOffset, uint32_t vertexStride,
                                                                const Context& context) const {
    bool skip = false;

    const auto& error_obj = context.error_obj;
    skip |= context.ValidateDeviceAddressFlags(error_obj.location.dot(Field::pCounterInfo).dot(Field::addressFlags),
                                               pCounterInfo->addressFlags);

    if (!enabled_features.transformFeedback) {
        skip |= LogError("VUID-vkCmdDrawIndirectByteCount2EXT-transformFeedback-02287", commandBuffer, error_obj.location,
                         "transformFeedback feature is not enabled.");
    }
    if (IsExtEnabled(extensions.vk_ext_transform_feedback) && !phys_dev_ext_props.transform_feedback_props.transformFeedbackDraw) {
        skip |= LogError("VUID-vkCmdDrawIndirectByteCount2EXT-transformFeedbackDraw-02288", commandBuffer, error_obj.location,
                         "VkPhysicalDeviceTransformFeedbackPropertiesEXT::transformFeedbackDraw is not supported");
    }
    if (vertexStride == 0 || vertexStride > phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBufferDataStride) {
        skip |= LogError("VUID-vkCmdDrawIndirectByteCount2EXT-vertexStride-02289", commandBuffer,
                         error_obj.location.dot(Field::vertexStride),
                         "(%" PRIu32 ") must not be 0 or larger than maxTransformFeedbackBufferDataStride (%" PRIu32 ").",
                         vertexStride, phys_dev_ext_props.transform_feedback_props.maxTransformFeedbackBufferDataStride);
    }
    if (!IsPointerAligned(pCounterInfo->addressRange.address, 4)) {
        skip |= LogError("VUID-vkCmdDrawIndirectByteCount2EXT-pInfo-13062", commandBuffer,
                         error_obj.location.dot(Field::pCounterInfo).dot(Field::addressRange).dot(Field::address),
                         "(0x%" PRIx64 ") must be aligned to 4 bytes.", pCounterInfo->addressRange.address);
    }
    if (!IsIntegerMultipleOf(counterOffset, 4)) {
        skip |= LogError("VUID-vkCmdDrawIndirectByteCount2EXT-counterOffset-09474", commandBuffer,
                         error_obj.location.dot(Field::counterOffset), "(%" PRIu32 ") must be a multiple of 4.", counterOffset);
    }
    if (!IsIntegerMultipleOf(vertexStride, 4)) {
        skip |= LogError("VUID-vkCmdDrawIndirectByteCount2EXT-vertexStride-09475", commandBuffer,
                         error_obj.location.dot(Field::vertexStride), "(%" PRIu32 ") must be a multiple of 4.", vertexStride);
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdBindIndexBuffer3KHR(VkCommandBuffer commandBuffer, const VkBindIndexBuffer3InfoKHR* pInfo,
                                                          const Context& context) const {
    bool skip = false;

    const auto& error_obj = context.error_obj;
    const Location info_loc = error_obj.location.dot(Field::pInfo);

    skip |= context.ValidateDeviceAddressFlags(info_loc.dot(Field::addressFlags), pInfo->addressFlags);

    if (pInfo->indexType == VK_INDEX_TYPE_NONE_KHR) {
        skip |= LogError("VUID-VkBindIndexBuffer3InfoKHR-indexType-13053", commandBuffer, info_loc.dot(Field::indexType),
                         "is VK_INDEX_TYPE_NONE_KHR.");
    } else if (pInfo->indexType == VK_INDEX_TYPE_UINT8) {
        if (!enabled_features.indexTypeUint8) {
            skip |= LogError("VUID-VkBindIndexBuffer3InfoKHR-indexType-13054", commandBuffer, info_loc.dot(Field::indexType),
                             "is VK_INDEX_TYPE_UINT8, but the indexTypeUint8 feature is not enabled.");
        }
    }

    if (pInfo->indexType != VK_INDEX_TYPE_NONE_KHR &&
        !IsPointerAligned(pInfo->addressRange.address, IndexTypeByteSize(pInfo->indexType))) {
        skip |= LogError("VUID-VkBindIndexBuffer3InfoKHR-addressRange-13052", commandBuffer,
                         info_loc.dot(Field::addressRange).dot(Field::address),
                         "(0x%" PRIx64 ") must be aligned to %" PRIu32 " bytes (the alignment for %s).",
                         pInfo->addressRange.address, IndexTypeByteSize(pInfo->indexType), string_VkIndexType(pInfo->indexType));
    }

    if (pInfo->addressRange.size == 0) {
        if (!enabled_features.nullDescriptor) {
            skip |= LogError("VUID-VkBindIndexBuffer3InfoKHR-None-13055", commandBuffer,
                             info_loc.dot(Field::addressRange).dot(Field::size),
                             "is 0, but the nullDescriptor feature is not enabled.");
        } else if (pInfo->addressRange.address != 0) {
            skip |= LogError("VUID-VkBindIndexBuffer3InfoKHR-addressRange-13056", commandBuffer,
                             info_loc.dot(Field::addressRange).dot(Field::size),
                             "is 0, but addressRange.address is (0x%" PRIx64 ") (must be zero to nullDescriptor).",
                             pInfo->addressRange.address);
        }
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset,
                                                 VkDeviceSize size, uint32_t data, const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;

    if (!IsIntegerMultipleOf(dstOffset, 4)) {
        const LogObjectList objlist(commandBuffer, dstBuffer);
        skip |= LogError("VUID-vkCmdFillBuffer-dstOffset-00025", objlist, error_obj.location.dot(Field::dstOffset),
                         "(%" PRIu64 ") is not a multiple of 4.", dstOffset);
    }

    if (size != VK_WHOLE_SIZE) {
        if (size <= 0) {
            const LogObjectList objlist(commandBuffer, dstBuffer);
            skip |= LogError("VUID-vkCmdFillBuffer-size-00026", objlist, error_obj.location.dot(Field::size),
                             "(%" PRIu64 ") must be greater than zero.", size);
        } else if (!IsIntegerMultipleOf(size, 4)) {
            const LogObjectList objlist(commandBuffer, dstBuffer);
            skip |= LogError("VUID-vkCmdFillBuffer-size-00028", objlist, error_obj.location.dot(Field::size),
                             "(%" PRIu64 ") is not a multiple of 4.", size);
        }
    }
    return skip;
}

bool Device::manual_PreCallValidateCmdFillMemoryKHR(VkCommandBuffer commandBuffer, const VkDeviceAddressRangeKHR* pDstRange,
                                                    VkAddressCommandFlagsKHR dstFlags, uint32_t data,
                                                    const Context& context) const {
    bool skip = false;

    const auto& error_obj = context.error_obj;
    skip |= context.ValidateDeviceAddressFlags(error_obj.location.dot(Field::dstFlags), dstFlags);

    if (!IsPointerAligned(pDstRange->address, 4)) {
        skip |= LogError("VUID-vkCmdFillMemoryKHR-pDstRange-13001", commandBuffer,
                         error_obj.location.dot(Field::pDstRange).dot(Field::address),
                         "(0x%" PRIx64 ") must be aligned to 4 bytes.", pDstRange->address);
    }
    if (!IsIntegerMultipleOf(pDstRange->size, 4)) {
        skip |= LogError("VUID-vkCmdFillMemoryKHR-pDstRange-13002", commandBuffer,
                         error_obj.location.dot(Field::pDstRange).dot(Field::size), "(%" PRIu64 ") is not a multiple of 4.",
                         pDstRange->size);
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdBindDescriptorBuffersEXT(VkCommandBuffer commandBuffer, uint32_t bufferCount,
                                                               const VkDescriptorBufferBindingInfoEXT* pBindingInfos,
                                                               const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;
    if (!enabled_features.descriptorBuffer) {
        skip |= LogError("VUID-vkCmdBindDescriptorBuffersEXT-None-08047", commandBuffer, error_obj.location,
                         "descriptorBuffer feature was not enabled.");
    }

    for (uint32_t i = 0; i < bufferCount; i++) {
        if (!vku::FindStructInPNextChain<VkBufferUsageFlags2CreateInfo>(pBindingInfos[i].pNext)) {
            skip |= context.ValidateFlags(error_obj.location.dot(Field::pBindingInfos, i).dot(Field::usage),
                                          vvl::FlagBitmask::VkBufferUsageFlagBits, AllVkBufferUsageFlagBits, pBindingInfos[i].usage,
                                          kRequiredFlags, "VUID-VkDescriptorBufferBindingInfoEXT-None-09499",
                                          "VUID-VkDescriptorBufferBindingInfoEXT-None-09500");
        }
    }

    return skip;
}

bool Instance::manual_PreCallValidateGetPhysicalDeviceExternalBufferProperties(
    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
    VkExternalBufferProperties* pExternalBufferProperties, const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;

    if (!vku::FindStructInPNextChain<VkBufferUsageFlags2CreateInfo>(pExternalBufferInfo->pNext)) {
        skip |= context.ValidateFlags(error_obj.location.dot(Field::pExternalBufferInfo).dot(Field::usage),
                                      vvl::FlagBitmask::VkBufferUsageFlagBits, AllVkBufferUsageFlagBits, pExternalBufferInfo->usage,
                                      kRequiredFlags, "VUID-VkPhysicalDeviceExternalBufferInfo-None-09499",
                                      "VUID-VkPhysicalDeviceExternalBufferInfo-None-09500");
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdPushDescriptorSet(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
                                                        VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount,
                                                        const VkWriteDescriptorSet* pDescriptorWrites,
                                                        const Context& context) const {
    return ValidateWriteDescriptorSet(context, context.error_obj.location, descriptorWriteCount, pDescriptorWrites);
}

bool Device::manual_PreCallValidateCmdPushDescriptorSet2(VkCommandBuffer commandBuffer,
                                                         const VkPushDescriptorSetInfo* pPushDescriptorSetInfo,
                                                         const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;
    skip |= ValidateWriteDescriptorSet(context, error_obj.location, pPushDescriptorSetInfo->descriptorWriteCount,
                                       pPushDescriptorSetInfo->pDescriptorWrites);
    if (pPushDescriptorSetInfo->layout == VK_NULL_HANDLE) {
        if (!enabled_features.dynamicPipelineLayout) {
            skip |= LogError("VUID-VkPushDescriptorSetInfo-None-09495", commandBuffer,
                             error_obj.location.dot(Field::pPushDescriptorSetInfo).dot(Field::layout), "is VK_NULL_HANDLE.");
        } else if (!vku::FindStructInPNextChain<VkPipelineLayoutCreateInfo>(pPushDescriptorSetInfo->pNext)) {
            skip |= LogError("VUID-VkPushDescriptorSetInfo-layout-09496", commandBuffer,
                             error_obj.location.dot(Field::pPushDescriptorSetInfo).dot(Field::layout),
                             "is VK_NULL_HANDLE and pNext is missing VkPipelineLayoutCreateInfo.");
        }
    }
    return skip;
}

bool Device::ValidateViewport(const VkViewport& viewport, VkCommandBuffer object, const Location& loc) const {
    bool skip = false;

    // Note: for numerical correctness
    //       - float comparisons should expect NaN (comparison always false).
    //       - VkPhysicalDeviceLimits::maxViewportDimensions is uint32_t, not float -> careful.

    const auto f_lte_u32_exact = [](const float v1_f, const uint32_t v2_u32) {
        if (std::isnan(v1_f)) return false;
        if (v1_f <= 0.0f) return true;

        float intpart;
        const float fract = modff(v1_f, &intpart);

        assert(std::numeric_limits<float>::radix == 2);
        const float u32_max_plus1 = ldexpf(1.0f, 32);  // hopefully exact
        if (intpart >= u32_max_plus1) return false;

        uint32_t v1_u32 = static_cast<uint32_t>(intpart);
        if (v1_u32 < v2_u32) {
            return true;
        } else if (v1_u32 == v2_u32 && fract == 0.0f) {
            return true;
        } else {
            return false;
        }
    };

    const auto f_lte_u32_direct = [](const float v1_f, const uint32_t v2_u32) {
        const float v2_f = static_cast<float>(v2_u32);  // not accurate for > radix^digits; and undefined rounding mode
        return (v1_f <= v2_f);
    };

    // width
    bool width_healthy = true;
    const auto max_w = phys_dev_props.limits.maxViewportDimensions[0];

    if (!(viewport.width > 0.0f)) {
        width_healthy = false;
        skip |= LogError("VUID-VkViewport-width-01770", object, loc.dot(Field::width), "(%f) is not greater than zero.",
                         viewport.width);
    } else if (!(f_lte_u32_exact(viewport.width, max_w) || f_lte_u32_direct(viewport.width, max_w))) {
        width_healthy = false;
        skip |= LogError("VUID-VkViewport-width-01771", object, loc.dot(Field::width),
                         "(%f) exceeds VkPhysicalDeviceLimits::maxViewportDimensions[0] (%" PRIu32 ").", viewport.width, max_w);
    }

    // height
    bool height_healthy = true;
    const bool negative_height_enabled =
        IsExtEnabled(extensions.vk_khr_maintenance1) || IsExtEnabled(extensions.vk_amd_negative_viewport_height);
    const auto max_h = phys_dev_props.limits.maxViewportDimensions[1];

    if (!negative_height_enabled && !(viewport.height > 0.0f)) {
        height_healthy = false;
        skip |= LogError("VUID-VkViewport-apiVersion-07917", object, loc.dot(Field::height), "(%f) is not greater zero.",
                         viewport.height);
    } else if (!(f_lte_u32_exact(fabsf(viewport.height), max_h) || f_lte_u32_direct(fabsf(viewport.height), max_h))) {
        height_healthy = false;

        skip |= LogError("VUID-VkViewport-height-01773", object, loc.dot(Field::height),
                         "absolute value (%f) exceeds VkPhysicalDeviceLimits::maxViewportDimensions[1] (%" PRIu32 ").",
                         viewport.height, max_h);
    }

    // x
    bool x_healthy = true;
    if (!(viewport.x >= phys_dev_props.limits.viewportBoundsRange[0])) {
        x_healthy = false;
        skip |= LogError("VUID-VkViewport-x-01774", object, loc.dot(Field::x),
                         "(%f) is less than VkPhysicalDeviceLimits::viewportBoundsRange[0] (%f).", viewport.x,
                         phys_dev_props.limits.viewportBoundsRange[0]);
    }

    // x + width
    if (x_healthy && width_healthy) {
        const float right_bound = viewport.x + viewport.width;
        if (right_bound > phys_dev_props.limits.viewportBoundsRange[1]) {
            skip |= LogError("VUID-VkViewport-x-01232", object, loc,
                             "x (%f) + width (%f) is %f which is greater than VkPhysicalDeviceLimits::viewportBoundsRange[1] (%f).",
                             viewport.x, viewport.width, right_bound, phys_dev_props.limits.viewportBoundsRange[1]);
        }
    }

    // y
    bool y_healthy = true;
    if (!(viewport.y >= phys_dev_props.limits.viewportBoundsRange[0])) {
        y_healthy = false;
        skip |= LogError("VUID-VkViewport-y-01775", object, loc.dot(Field::y),
                         "(%f) is less than VkPhysicalDeviceLimits::viewportBoundsRange[0] (%f).", viewport.y,
                         phys_dev_props.limits.viewportBoundsRange[0]);
    } else if (negative_height_enabled && viewport.y > phys_dev_props.limits.viewportBoundsRange[1]) {
        y_healthy = false;
        skip |= LogError("VUID-VkViewport-y-01776", object, loc.dot(Field::y),
                         "(%f) exceeds VkPhysicalDeviceLimits::viewportBoundsRange[1] (%f).", viewport.y,
                         phys_dev_props.limits.viewportBoundsRange[1]);
    }

    // y + height
    if (y_healthy && height_healthy) {
        const float boundary = viewport.y + viewport.height;

        if (boundary > phys_dev_props.limits.viewportBoundsRange[1]) {
            skip |= LogError("VUID-VkViewport-y-01233", object, loc.dot(Field::y),
                             "(%f) + height (%f) is %f which exceeds VkPhysicalDeviceLimits::viewportBoundsRange[1] (%f).",
                             viewport.y, viewport.height, boundary, phys_dev_props.limits.viewportBoundsRange[1]);
        } else if (negative_height_enabled && boundary < phys_dev_props.limits.viewportBoundsRange[0]) {
            skip |= LogError("VUID-VkViewport-y-01777", object, loc.dot(Field::y),
                             "(%f) + height (%f) is %f which is less than VkPhysicalDeviceLimits::viewportBoundsRange[0] (%f).",
                             viewport.y, viewport.height, boundary, phys_dev_props.limits.viewportBoundsRange[0]);
        }
    }

    if (!IsExtEnabled(extensions.vk_ext_depth_range_unrestricted)) {
        // minDepth
        if (!(viewport.minDepth >= 0.0) || !(viewport.minDepth <= 1.0)) {
            skip |= LogError("VUID-VkViewport-minDepth-01234", object, loc.dot(Field::minDepth), "is %f.", viewport.minDepth);
        }

        // maxDepth
        if (!(viewport.maxDepth >= 0.0) || !(viewport.maxDepth <= 1.0)) {
            skip |= LogError("VUID-VkViewport-maxDepth-01235", object, loc.dot(Field::maxDepth), "is %f.", viewport.maxDepth);
        }
    }

    return skip;
}

bool Device::manual_PreCallValidateFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
                                                      const VkCommandBuffer* pCommandBuffers, const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;

    // 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()
    skip |= context.ValidateArray(error_obj.location.dot(Field::commandBufferCount), error_obj.location.dot(Field::pCommandBuffers),
                                  commandBufferCount, &pCommandBuffers, true, true, kVUIDUndefined,
                                  "VUID-vkFreeCommandBuffers-pCommandBuffers-00048");

    if (pCommandBuffers && commandBufferCount > 1) {
        vvl::unordered_map<VkCommandBuffer, uint32_t> seen_cb;
        for (uint32_t i = 0; i < commandBufferCount; i++) {
            const VkCommandBuffer next_cb = pCommandBuffers[i];
            if (next_cb == VK_NULL_HANDLE) {
                continue;
            }
            auto it = seen_cb.find(next_cb);
            if (it != seen_cb.end()) {
                const LogObjectList objlist(commandPool, next_cb);
                skip |= LogError("VUID-vkFreeCommandBuffers-pCommandBuffers-00048", objlist,
                                 context.error_obj.location.dot(Field::pCommandBuffers, i),
                                 "(%s) was already freed in pCommandBuffers[%" PRIu32
                                 "] and this is trying to do an invalid double free.",
                                 FormatHandle(next_cb).c_str(), it->second);
                break;
            }
            seen_cb[next_cb] = i;
        }
    }

    return skip;
}

bool Device::manual_PreCallValidateBeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo* pBeginInfo,
                                                      const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;

    // pBeginInfo->pInheritanceInfo can be a non-null invalid pointer. If not secondary command buffer we need to ignore
    if (!error_obj.handle_data->command_buffer.is_secondary) {
        return skip;
    }

    if (pBeginInfo->pInheritanceInfo) {
        const VkCommandBufferInheritanceInfo& info = *pBeginInfo->pInheritanceInfo;
        const Location begin_info_loc = error_obj.location.dot(Field::pBeginInfo);
        const Location inheritance_loc = begin_info_loc.dot(Field::pInheritanceInfo);

        skip |= ValidateCommandBufferInheritanceInfo(context, info, inheritance_loc);

        // Explicit VUs
        if (!enabled_features.inheritedQueries && info.occlusionQueryEnable == VK_TRUE) {
            skip |= LogError(
                "VUID-VkCommandBufferInheritanceInfo-occlusionQueryEnable-00056", commandBuffer, error_obj.location,
                "inheritedQueries feature is disabled, but pBeginInfo->pInheritanceInfo->occlusionQueryEnable is VK_TRUE.");
        }

        if (enabled_features.inheritedQueries) {
            skip |= context.ValidateFlags(inheritance_loc.dot(Field::queryFlags), vvl::FlagBitmask::VkQueryControlFlagBits,
                                          AllVkQueryControlFlagBits, info.queryFlags, kOptionalFlags,
                                          "VUID-VkCommandBufferInheritanceInfo-queryFlags-00057");
        } else {  // !inheritedQueries
            skip |= context.ValidateReservedFlags(inheritance_loc.dot(Field::queryFlags), info.queryFlags,
                                                  "VUID-VkCommandBufferInheritanceInfo-queryFlags-02788");
        }

        if (enabled_features.pipelineStatisticsQuery) {
            skip |= context.ValidateFlags(inheritance_loc.dot(Field::pipelineStatistics),
                                          vvl::FlagBitmask::VkQueryPipelineStatisticFlagBits, AllVkQueryPipelineStatisticFlagBits,
                                          info.pipelineStatistics, kOptionalFlags,
                                          "VUID-VkCommandBufferInheritanceInfo-pipelineStatistics-02789");
        } else {  // !pipelineStatisticsQuery
            skip |= context.ValidateReservedFlags(inheritance_loc.dot(Field::pipelineStatistics), info.pipelineStatistics,
                                                  "VUID-VkCommandBufferInheritanceInfo-pipelineStatistics-00058");
        }

        if (const auto* conditional_rendering =
                vku::FindStructInPNextChain<VkCommandBufferInheritanceConditionalRenderingInfoEXT>(info.pNext)) {
            if (!enabled_features.inheritedConditionalRendering && conditional_rendering->conditionalRenderingEnable == VK_TRUE) {
                skip |= LogError("VUID-VkCommandBufferInheritanceConditionalRenderingInfoEXT-conditionalRenderingEnable-01977",
                                 commandBuffer,
                                 inheritance_loc.pNext(Struct::VkCommandBufferInheritanceConditionalRenderingInfoEXT,
                                                       Field::conditionalRenderingEnable),
                                 "is VK_TRUE but the inheritedConditionalRendering feature was not enabled.");
            }
        }

        if (auto inherited_viewport_scissor_info =
                vku::FindStructInPNextChain<VkCommandBufferInheritanceViewportScissorInfoNV>(info.pNext)) {
            if (!enabled_features.multiViewport && inherited_viewport_scissor_info->viewportScissor2D &&
                inherited_viewport_scissor_info->viewportDepthCount != 1) {
                skip |= LogError(
                    "VUID-VkCommandBufferInheritanceViewportScissorInfoNV-viewportScissor2D-04783", commandBuffer,
                    inheritance_loc.pNext(Struct::VkCommandBufferInheritanceViewportScissorInfoNV, Field::viewportScissor2D),
                    "is VK_TRUE and viewportDepthCount is %" PRIu32 " (not 1), but the multiViewport feature was not enabled.",
                    inherited_viewport_scissor_info->viewportDepthCount);
            }
        }
    }
    return skip;
}

bool Device::manual_PreCallValidateCmdSetPrimitiveRestartIndexEXT(VkCommandBuffer commandBuffer, uint32_t primitiveRestartIndex,
                                                                  const Context& context) const {
    bool skip = false;
    if (!enabled_features.primitiveRestartIndex) {
        skip |= LogError("VUID-vkCmdSetPrimitiveRestartIndexEXT-primitiveRestartIndex-12395", commandBuffer,
                         context.error_obj.location, "primitiveRestartIndex feature was not enabled.");
    }
    return skip;
}

static size_t ComponentTypeBytesPerElement(VkComponentTypeKHR component_type) {
    switch (component_type) {
        case VK_COMPONENT_TYPE_SINT8_KHR:
        case VK_COMPONENT_TYPE_UINT8_KHR:
        case VK_COMPONENT_TYPE_FLOAT_E4M3_NV:
        case VK_COMPONENT_TYPE_FLOAT_E5M2_NV:
        case VK_COMPONENT_TYPE_SINT8_PACKED_NV:
        case VK_COMPONENT_TYPE_UINT8_PACKED_NV:
            return 1;
        case VK_COMPONENT_TYPE_FLOAT16_KHR:
        case VK_COMPONENT_TYPE_SINT16_KHR:
        case VK_COMPONENT_TYPE_UINT16_KHR:
            return 2;
        case VK_COMPONENT_TYPE_FLOAT32_KHR:
        case VK_COMPONENT_TYPE_SINT32_KHR:
        case VK_COMPONENT_TYPE_UINT32_KHR:
            return 4;
        case VK_COMPONENT_TYPE_FLOAT64_KHR:
        case VK_COMPONENT_TYPE_SINT64_KHR:
        case VK_COMPONENT_TYPE_UINT64_KHR:
            return 8;
        default:
            return 0;
    }
}

static bool IsFloatComponentType(VkComponentTypeKHR component_type) {
    switch (component_type) {
        case VK_COMPONENT_TYPE_FLOAT_E4M3_NV:
        case VK_COMPONENT_TYPE_FLOAT_E5M2_NV:
        case VK_COMPONENT_TYPE_FLOAT16_KHR:
        case VK_COMPONENT_TYPE_FLOAT32_KHR:
        case VK_COMPONENT_TYPE_FLOAT64_KHR:
            return true;
        default:
            return false;
    }
}

bool Device::ValidateVkConvertCooperativeVectorMatrixInfoNV(const LogObjectList& objlist,
                                                            const VkConvertCooperativeVectorMatrixInfoNV& info,
                                                            const Location& info_loc) const {
    bool skip = false;

    // size_t to match the stride used in the API
    const size_t src_element_size = ComponentTypeBytesPerElement(info.srcComponentType);
    const size_t dst_element_size = ComponentTypeBytesPerElement(info.dstComponentType);

    if (info.srcLayout == VK_COOPERATIVE_VECTOR_MATRIX_LAYOUT_ROW_MAJOR_NV) {
        if (info.srcStride < info.numColumns * src_element_size) {
            skip |= LogError("VUID-VkConvertCooperativeVectorMatrixInfoNV-srcLayout-10077", objlist, info_loc.dot(Field::srcStride),
                             "(%zu) must be at least as large as numColumns (%" PRIu32 ") times source element size (%zu)",
                             info.srcStride, info.numColumns, src_element_size);
        }
    }
    if (info.srcLayout == VK_COOPERATIVE_VECTOR_MATRIX_LAYOUT_COLUMN_MAJOR_NV) {
        if (info.srcStride < info.numRows * src_element_size) {
            skip |= LogError("VUID-VkConvertCooperativeVectorMatrixInfoNV-srcLayout-10077", objlist, info_loc.dot(Field::srcStride),
                             "(%zu) must be at least as large as numRows (%" PRIu32 ") times source element size (%zu)",
                             info.srcStride, info.numRows, src_element_size);
        }
    }
    if (info.srcLayout == VK_COOPERATIVE_VECTOR_MATRIX_LAYOUT_ROW_MAJOR_NV ||
        info.srcLayout == VK_COOPERATIVE_VECTOR_MATRIX_LAYOUT_COLUMN_MAJOR_NV) {
        if (!IsIntegerMultipleOf(info.srcStride, src_element_size)) {
            skip |= LogError("VUID-VkConvertCooperativeVectorMatrixInfoNV-srcLayout-10077", objlist, info_loc.dot(Field::srcStride),
                             "(%zu) must be a multiple of source element size (%zu)", info.srcStride, src_element_size);
        }
    }

    if (info.dstLayout == VK_COOPERATIVE_VECTOR_MATRIX_LAYOUT_ROW_MAJOR_NV) {
        if (info.dstStride < info.numColumns * dst_element_size) {
            skip |= LogError("VUID-VkConvertCooperativeVectorMatrixInfoNV-dstLayout-10078", objlist, info_loc.dot(Field::dstStride),
                             "(%zu) must be at least as large as numColumns (%" PRIu32 ") times destination element size (%zu)",
                             info.dstStride, info.numColumns, dst_element_size);
        }
    }
    if (info.dstLayout == VK_COOPERATIVE_VECTOR_MATRIX_LAYOUT_COLUMN_MAJOR_NV) {
        if (info.dstStride < info.numRows * dst_element_size) {
            skip |= LogError("VUID-VkConvertCooperativeVectorMatrixInfoNV-dstLayout-10078", objlist, info_loc.dot(Field::dstStride),
                             "(%zu) must be at least as large as numRows (%" PRIu32 ") times destination element size (%zu)",
                             info.dstStride, info.numRows, dst_element_size);
        }
    }
    if (info.dstLayout == VK_COOPERATIVE_VECTOR_MATRIX_LAYOUT_ROW_MAJOR_NV ||
        info.dstLayout == VK_COOPERATIVE_VECTOR_MATRIX_LAYOUT_COLUMN_MAJOR_NV) {
        if (!IsIntegerMultipleOf(info.dstStride, dst_element_size)) {
            skip |= LogError("VUID-VkConvertCooperativeVectorMatrixInfoNV-dstLayout-10078", objlist, info_loc.dot(Field::dstStride),
                             "(%zu) must be a multiple of destination element size (%zu)", info.dstStride, dst_element_size);
        }
    }

    if (info.srcComponentType != info.dstComponentType) {
        bool ok =
            IsFloatComponentType(info.srcComponentType) && IsFloatComponentType(info.dstComponentType) &&
            (info.srcComponentType == VK_COMPONENT_TYPE_FLOAT16_KHR || info.srcComponentType == VK_COMPONENT_TYPE_FLOAT32_KHR ||
             info.dstComponentType == VK_COMPONENT_TYPE_FLOAT16_KHR || info.dstComponentType == VK_COMPONENT_TYPE_FLOAT32_KHR);
        if (!ok) {
            skip |= LogError("VUID-VkConvertCooperativeVectorMatrixInfoNV-srcComponentType-10081", objlist, info_loc,
                             "Unsupported conversion from %s to %s", string_VkComponentTypeKHR(info.srcComponentType),
                             string_VkComponentTypeKHR(info.dstComponentType));
        }
    }
    if ((info.dstComponentType == VK_COMPONENT_TYPE_FLOAT_E4M3_NV || info.dstComponentType == VK_COMPONENT_TYPE_FLOAT_E5M2_NV) &&
        info.dstLayout != VK_COOPERATIVE_VECTOR_MATRIX_LAYOUT_INFERENCING_OPTIMAL_NV &&
        info.dstLayout != VK_COOPERATIVE_VECTOR_MATRIX_LAYOUT_TRAINING_OPTIMAL_NV) {
        skip |=
            LogError("VUID-VkConvertCooperativeVectorMatrixInfoNV-dstComponentType-10082", objlist,
                     info_loc.dot(Field::srcComponentType), "%s cannot be converted to destination layout %s",
                     string_VkComponentTypeKHR(info.srcComponentType), string_VkCooperativeVectorMatrixLayoutNV(info.dstLayout));
    }

    return skip;
}

static size_t ComputeMinSize(VkComponentTypeKHR component_type, VkCooperativeVectorMatrixLayoutNV layout, uint32_t num_rows,
                             uint32_t num_columns, size_t stride) {
    size_t min_size = 0;
    size_t element_size = ComponentTypeBytesPerElement(component_type);
    if (layout == VK_COOPERATIVE_VECTOR_MATRIX_LAYOUT_ROW_MAJOR_NV) {
        min_size = (num_rows - 1) * stride + num_columns * element_size;
    } else if (layout == VK_COOPERATIVE_VECTOR_MATRIX_LAYOUT_COLUMN_MAJOR_NV) {
        min_size = (num_columns - 1) * stride + num_rows * element_size;
    }
    return min_size;
}

bool Device::manual_PreCallValidateConvertCooperativeVectorMatrixNV(VkDevice device,
                                                                    const VkConvertCooperativeVectorMatrixInfoNV* pInfo,
                                                                    const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;

    const Location info_loc = error_obj.location.dot(Field::pInfo);

    if (pInfo->srcData.hostAddress == nullptr && pInfo->dstData.hostAddress != nullptr) {
        skip |= LogError("VUID-vkConvertCooperativeVectorMatrixNV-pInfo-10073", device,
                         info_loc.dot(Field::dstData).dot(Field::hostAddress), "(%p) must be null", pInfo->dstData.hostAddress);
    }

    if (pInfo->srcData.hostAddress != nullptr) {
        size_t min_src_size =
            ComputeMinSize(pInfo->srcComponentType, pInfo->srcLayout, pInfo->numRows, pInfo->numColumns, pInfo->srcStride);
        if (pInfo->srcSize < min_src_size) {
            skip |= LogError("VUID-vkConvertCooperativeVectorMatrixNV-pInfo-10074", device, info_loc.dot(Field::srcSize),
                             "(%zu) less than minimum size for row/col-major layout (%zu)", pInfo->srcSize, min_src_size);
        }
    }

    if (pInfo->dstData.hostAddress != nullptr) {
        size_t min_dst_size =
            ComputeMinSize(pInfo->dstComponentType, pInfo->dstLayout, pInfo->numRows, pInfo->numColumns, pInfo->dstStride);
        if (*pInfo->pDstSize < min_dst_size) {
            skip |= LogError("VUID-vkConvertCooperativeVectorMatrixNV-pInfo-10075", device, info_loc.dot(Field::pDstSize),
                             "(%zu) less than minimum size for row/col-major layout (%zu)", *pInfo->pDstSize, min_dst_size);
        }
    }

    if (pInfo->dstData.hostAddress != nullptr) {
        vvl::range<size_t> src_range((uintptr_t)pInfo->srcData.hostAddress, (uintptr_t)pInfo->srcData.hostAddress + pInfo->srcSize);
        vvl::range<size_t> dst_range((uintptr_t)pInfo->dstData.hostAddress,
                                     (uintptr_t)pInfo->dstData.hostAddress + *pInfo->pDstSize);
        if (src_range.intersects(dst_range)) {
            skip |= LogError("VUID-vkConvertCooperativeVectorMatrixNV-pInfo-10076", device, info_loc,
                             "Source [0x%zx,0x%zx) and destination [0x%zx,0x%zx) ranges overlap", src_range.begin, src_range.end,
                             dst_range.begin, dst_range.end);
        }
    }

    skip |= ValidateVkConvertCooperativeVectorMatrixInfoNV(device, *pInfo, info_loc);

    return skip;
}

bool Device::manual_PreCallValidateCmdConvertCooperativeVectorMatrixNV(VkCommandBuffer commandBuffer, uint32_t infoCount,
                                                                       const VkConvertCooperativeVectorMatrixInfoNV* pInfos,
                                                                       const Context& context) const {
    bool skip = false;
    const auto& error_obj = context.error_obj;

    std::vector<vvl::range<VkDeviceAddress>> src_memory_ranges;
    std::vector<vvl::range<VkDeviceAddress>> dst_memory_ranges;

    for (uint32_t i = 0; i < infoCount; ++i) {
        auto const& info = pInfos[i];

        const Location info_loc = error_obj.location.dot(Field::pInfos, i);

        if (!IsPointerAligned(info.srcData.deviceAddress, 64)) {
            skip |= LogError("VUID-vkCmdConvertCooperativeVectorMatrixNV-pInfo-10084", commandBuffer,
                             info_loc.dot(Field::srcData).dot(Field::deviceAddress), "(0x%" PRIx64 ") must be 64 byte aligned",
                             info.srcData.deviceAddress);
        }
        if (!IsPointerAligned(info.dstData.deviceAddress, 64)) {
            skip |= LogError("VUID-vkCmdConvertCooperativeVectorMatrixNV-pInfo-10085", commandBuffer,
                             info_loc.dot(Field::dstData).dot(Field::deviceAddress), "(0x%" PRIx64 ") must be 64 byte aligned",
                             info.dstData.deviceAddress);
        }

        size_t min_src_size = ComputeMinSize(info.srcComponentType, info.srcLayout, info.numRows, info.numColumns, info.srcStride);
        if (info.srcSize < min_src_size) {
            skip |= LogError("VUID-vkCmdConvertCooperativeVectorMatrixNV-pInfo-10086", device, info_loc.dot(Field::srcSize),
                             "(%zu) less than minimum size for row/col-major layout (%zu)", info.srcSize, min_src_size);
        }

        size_t min_dst_size = ComputeMinSize(info.dstComponentType, info.dstLayout, info.numRows, info.numColumns, info.dstStride);
        if (*info.pDstSize < min_dst_size) {
            skip |= LogError("VUID-vkCmdConvertCooperativeVectorMatrixNV-pInfo-10087", device, info_loc.dot(Field::pDstSize),
                             "(%zu) less than minimum size for row/col-major layout (%zu)", *info.pDstSize, min_dst_size);
        }

        src_memory_ranges.emplace_back(info.srcData.deviceAddress, info.srcData.deviceAddress + info.srcSize);
        dst_memory_ranges.emplace_back(info.dstData.deviceAddress, info.dstData.deviceAddress + *info.pDstSize);

        skip |= ValidateVkConvertCooperativeVectorMatrixInfoNV(commandBuffer, info, info_loc);
    }

    std::sort(src_memory_ranges.begin(), src_memory_ranges.end());
    std::sort(dst_memory_ranges.begin(), dst_memory_ranges.end());

    // Memory ranges are sorted, so looking for overlaps can be done in linear time
    auto src_ranges_it = src_memory_ranges.cbegin();
    auto dst_ranges_it = dst_memory_ranges.cbegin();

    while (src_ranges_it != src_memory_ranges.cend() && dst_ranges_it != dst_memory_ranges.cend()) {
        if (src_ranges_it->intersects(*dst_ranges_it)) {
            skip |= LogError("VUID-vkCmdConvertCooperativeVectorMatrixNV-None-10088", commandBuffer, error_obj.location,
                             "Source [0x%" PRIx64 ", 0x%" PRIx64 ") and destination [0x%" PRIx64 ", 0x%" PRIx64 ") ranges overlap",
                             src_ranges_it->begin, src_ranges_it->end, dst_ranges_it->begin, dst_ranges_it->end);
        }

        if (*src_ranges_it < *dst_ranges_it) {
            ++src_ranges_it;
        } else {
            ++dst_ranges_it;
        }
    }

    return skip;
}

bool Device::manual_PreCallValidateCmdBeginPerTileExecutionQCOM(VkCommandBuffer commandBuffer,
                                                                const VkPerTileBeginInfoQCOM *pPerTileBeginInfo,
                                                                const Context &context) const {
    bool skip = false;

    if (!enabled_features.tileShadingPerTileDispatch && !enabled_features.tileShadingPerTileDraw) {
        skip |= LogError("VUID-vkCmdBeginPerTileExecutionQCOM-None-10665",
                         commandBuffer, context.error_obj.location,
                         "VkPhysicalDeviceTileShadingFeaturesQCOM::tileShadingPerTileDispatch and "
                         "VkPhysicalDeviceTileShadingFeaturesQCOM::tileShadingPerTileDraw features are not enabled.");
    }

    return skip;
}

}  // namespace stateless
