/* 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.
 * Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
 *
 * 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 <cassert>
#include <sstream>
#include <string>
#include <vector>

#include <vulkan/vk_enum_string_helper.h>
#include "core_validation.h"
#include "generated/spirv_grammar_helper.h"
#include "utils/shader_utils.h"

bool CoreChecks::ValidateInterfaceVertexInput(const PIPELINE_STATE &pipeline, const SPIRV_MODULE_STATE &module_state,
                                              const EntryPoint &entrypoint, const Location &create_info_loc) const {
    bool skip = false;
    safe_VkPipelineVertexInputStateCreateInfo const *vi = pipeline.vertex_input_state->input_state;
    const Location vi_loc = create_info_loc.dot(Field::pVertexInputState);

    struct AttribInputPair {
        const VkFormat *attribute_input = nullptr;
        const Instruction *shader_input = nullptr;
        uint32_t attribute_index = 0;
    };
    // For vertex input, we only need to care about Location.
    // You are not allowed to offset into the Component words
    // or have 2 variables in a location
    std::map<uint32_t, AttribInputPair> location_map;

    if (vi) {
        for (uint32_t i = 0; i < vi->vertexAttributeDescriptionCount; ++i) {
            // Vertex input attributes use VkFormat, but only to make use of how they define sizes, things such as
            // depth/multi-plane/compressed will never be used here because they would mean nothing. So we can ensure these are
            // "standard" color formats being used
            const VkFormat format = vi->pVertexAttributeDescriptions[i].format;
            const uint32_t format_size = vkuFormatElementSize(format);
            // Vulkan Spec: Location is made up of 16 bytes, never can have 0 Locations
            const uint32_t bytes_in_location = 16;
            const uint32_t num_locations = ((format_size - 1) / bytes_in_location) + 1;
            for (uint32_t j = 0; j < num_locations; ++j) {
                const uint32_t index = vi->pVertexAttributeDescriptions[i].location + j;
                location_map[index].attribute_input = &(vi->pVertexAttributeDescriptions[i].format);
                location_map[index].attribute_index = i;
            }
        }
    }

    for (const auto *variable_ptr : entrypoint.user_defined_interface_variables) {
        const auto &variable = *variable_ptr;
        if ((variable.storage_class != spv::StorageClassInput)) {
            continue;  // not an input interface
        }
        // It is possible to have a struct block for the vertex input.
        // All members of struct must all have Locations or none of them will.
        // If the interface variable doesn't have the Locations, find them inside the struct members
        if (!variable.type_struct_info) {
            for (const auto &slot : variable.interface_slots) {
                location_map[slot.Location()].shader_input = &variable.base_type;
            }
        } else if (variable.decorations.location != kInvalidSpirvValue) {
            // Variable is decorated with Location
            uint32_t location = variable.decorations.location;
            for (uint32_t i = 0; i < variable.type_struct_info->members.size(); i++) {
                const auto &member = variable.type_struct_info->members[i];
                // can be 64-bit formats in the struct
                const uint32_t num_locations = module_state.GetLocationsConsumedByType(member.id);
                for (uint32_t j = 0; j < num_locations; ++j) {
                    location_map[location + j].shader_input = member.insn;
                }
                location += num_locations;
            }
        } else {
            // Can't be nested so only need to look at first level of members
            for (const auto &member : variable.type_struct_info->members) {
                location_map[member.decorations->location].shader_input = member.insn;
            }
        }
    }

    for (const auto &location_it : location_map) {
        const auto location = location_it.first;
        const auto attribute_input = location_it.second.attribute_input;
        const auto shader_input = location_it.second.shader_input;

        if (attribute_input && !shader_input) {
            skip |= LogPerformanceWarning(kVUID_Core_Shader_OutputNotConsumed, module_state.handle(), vi_loc,
                                          "Vertex attribute at location %" PRIu32 " not consumed by vertex shader.", location);
        } else if (!attribute_input && shader_input) {
            skip |= LogError("VUID-VkGraphicsPipelineCreateInfo-Input-07904", module_state.handle(),
                             vi_loc.dot(Field::pVertexAttributeDescriptions),
                             "does not have a Location %" PRIu32 " but vertex shader has an input variable at that Location.",
                             location);
        } else if (attribute_input && shader_input) {
            const VkFormat attribute_format = *attribute_input;
            const auto attribute_type = GetFormatType(attribute_format);
            const uint32_t var_base_type_id = shader_input->ResultId();
            const auto var_numeric_type = module_state.GetNumericType(var_base_type_id);

            // Type checking
            if (!(attribute_type & var_numeric_type)) {
                skip |=
                    LogError("VUID-VkGraphicsPipelineCreateInfo-Input-08733", module_state.handle(),
                             vi_loc.dot(Field::pVertexAttributeDescriptions, location_it.second.attribute_index).dot(Field::format),
                             "(%s) at Location %" PRIu32 " does not match vertex shader input type (%s).",
                             string_VkFormat(attribute_format), location, module_state.DescribeType(var_base_type_id).c_str());
            } else {
                // 64-bit can't be used if both the Vertex Attribute AND Shader Input Variable are both not 64-bit.
                const bool attribute64 = vkuFormatIs64bit(attribute_format);
                const bool shader64 = module_state.GetBaseTypeInstruction(var_base_type_id)->GetBitWidth() == 64;
                if (attribute64 && !shader64) {
                    skip |= LogError(
                        "VUID-VkGraphicsPipelineCreateInfo-pVertexInputState-08929", module_state.handle(),
                        vi_loc.dot(Field::pVertexAttributeDescriptions, location_it.second.attribute_index).dot(Field::format),
                        "(%s) is a 64-bit format, but at Location %" PRIu32 " the vertex shader input is 32-bit type (%s).",
                        string_VkFormat(attribute_format), location, module_state.DescribeType(var_base_type_id).c_str());
                } else if (!attribute64 && shader64) {
                    skip |= LogError(
                        "VUID-VkGraphicsPipelineCreateInfo-pVertexInputState-08930", module_state.handle(),
                        vi_loc.dot(Field::pVertexAttributeDescriptions, location_it.second.attribute_index).dot(Field::format),
                        "(%s) is a 64-bit format, but at Location %" PRIu32 " the vertex shader input is 64-bit type (%s).",
                        string_VkFormat(attribute_format), location, module_state.DescribeType(var_base_type_id).c_str());
                } else if (attribute64 && shader64) {
                    // Unlike 32-bit, the components for 64-bit inputs have to match exactly
                    const uint32_t attribute_components = vkuFormatComponentCount(attribute_format);
                    const uint32_t input_components = module_state.GetNumComponentsInBaseType(shader_input);
                    if (attribute_components < input_components) {
                        skip |= LogError(
                            "VUID-VkGraphicsPipelineCreateInfo-pVertexInputState-09198", module_state.handle(),
                            vi_loc.dot(Field::pVertexAttributeDescriptions, location_it.second.attribute_index).dot(Field::format),
                            "(%s) is a %" PRIu32 "-wide 64-bit format, but at location %" PRIu32
                            " the vertex shader input is %" PRIu32
                            "-wide 64-bit type (%s). (64-bit vertex input don't have default values and require "
                            "components to match what is used in the shader)",
                            string_VkFormat(attribute_format), attribute_components, location, input_components,
                            module_state.DescribeType(var_base_type_id).c_str());
                    }
                }
            }
        } else {            // !attrib && !input
            assert(false);  // at least one exists in the map
        }
    }

    return skip;
}

bool CoreChecks::ValidateInterfaceFragmentOutput(const PIPELINE_STATE &pipeline, const SPIRV_MODULE_STATE &module_state,
                                                 const EntryPoint &entrypoint, const Location &create_info_loc) const {
    bool skip = false;
    const auto *ms_state = pipeline.MultisampleState();
    if (!pipeline.IsDynamic(VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT) && ms_state && ms_state->alphaToCoverageEnable) {
        // TODO - DualSource blend has two outputs at location zero, so Index == 0 is the one that's required.
        // Currently lack support to test each index.
        if (!entrypoint.has_alpha_to_coverage_variable && !pipeline.DualSourceBlending()) {
            skip |= LogError("VUID-VkGraphicsPipelineCreateInfo-alphaToCoverageEnable-08891", module_state.handle(),
                             create_info_loc.dot(Field::pMultisampleState).dot(Field::alphaToCoverageEnable),
                             "is VK_TRUE, but the fragment shader doesn't declare a variable that covers "
                             "Location 0, Component 3.");
        }
    }
    return skip;
}

bool CoreChecks::ValidateBuiltinLimits(const SPIRV_MODULE_STATE &module_state, const EntryPoint &entrypoint,
                                       const StageCreateInfo &create_info, const Location &loc) const {
    bool skip = false;

    // Currently all builtin tested are only found in fragment shaders
    if (entrypoint.execution_model != spv::ExecutionModelFragment) {
        return skip;
    }

    for (const auto *variable : entrypoint.built_in_variables) {
        // Currently don't need to search in structs
        // Handles both the input and output sampleMask
        if (variable->decorations.builtin == spv::BuiltInSampleMask &&
            variable->array_size > phys_dev_props.limits.maxSampleMaskWords) {
            const char *vuid = create_info.pipeline ? "VUID-VkPipelineShaderStageCreateInfo-maxSampleMaskWords-00711"
                                                    : "VUID-VkShaderCreateInfoEXT-pCode-08451";
            skip |= LogError(vuid, module_state.handle(), loc,
                             "The BuiltIns SampleMask array sizes is %" PRIu32
                             " which exceeds "
                             "maxSampleMaskWords of %" PRIu32 ".",
                             variable->array_size, phys_dev_props.limits.maxSampleMaskWords);
            break;
        }
    }

    return skip;
}

bool CoreChecks::ValidatePrimitiveTopology(const SPIRV_MODULE_STATE &module_state, const EntryPoint &entrypoint,
                                           const StageCreateInfo &create_info, const Location &loc) const {
    bool skip = false;

    if (!create_info.pipeline || !create_info.pipeline->pre_raster_state || !create_info.pipeline->InputAssemblyState() ||
        entrypoint.stage != VK_SHADER_STAGE_GEOMETRY_BIT) {
        return skip;
    }

    const auto &pipeline = *create_info.pipeline;

    bool has_tess = false;
    VkPrimitiveTopology topology = pipeline.InputAssemblyState()->topology;
    for (uint32_t i = 0; i < pipeline.stage_states.size(); i++) {
        auto &stage_state = pipeline.stage_states[i];
        const VkShaderStageFlagBits stage = stage_state.GetStage();
        if (stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) {
            has_tess = true;
            if (stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) {
                topology = stage_state.entrypoint->execution_mode.primitive_topology;
            }
        }
    }

    VkPrimitiveTopology geom_topology = entrypoint.execution_mode.input_primitive_topology;
    bool mismatch = false;
    mismatch |= (topology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST && geom_topology != VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
    mismatch |=
        IsValueIn(topology, {VK_PRIMITIVE_TOPOLOGY_LINE_LIST, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
                             VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY}) &&
        !IsValueIn(geom_topology,
                   {VK_PRIMITIVE_TOPOLOGY_LINE_LIST, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
                    VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY});
    mismatch |= IsValueIn(topology, {VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
                                     VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY,
                                     VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY}) &&
                !IsValueIn(geom_topology, {VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
                                           VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY,
                                           VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY});
    if (mismatch) {
        if (has_tess) {
            skip |= LogError("VUID-VkGraphicsPipelineCreateInfo-pStages-00739", module_state.handle(), loc,
                             "SPIR-V (Geometry stage) expects input topology %s, but tessellation evaluation shader output topology is %s.",
                             string_VkPrimitiveTopology(geom_topology), string_VkPrimitiveTopology(topology));
        } else {
            skip |= LogError("VUID-VkGraphicsPipelineCreateInfo-pStages-00738", module_state.handle(), loc,
                             "SPIR-V (Geometry stage) expects input topology %s, but pipeline was created with primitive topology %s.",
                             string_VkPrimitiveTopology(geom_topology), string_VkPrimitiveTopology(topology));
        }
    }

    return skip;
}

bool CoreChecks::ValidateShaderStageInputOutputLimits(const SPIRV_MODULE_STATE &module_state, VkShaderStageFlagBits stage,
                                                      const EntryPoint &entrypoint, const Location &loc) const {
    if (stage == VK_SHADER_STAGE_COMPUTE_BIT || stage == VK_SHADER_STAGE_ALL_GRAPHICS || stage == VK_SHADER_STAGE_ALL) {
        return false;
    }

    bool skip = false;
    auto const &limits = phys_dev_props.limits;

    const uint32_t num_vertices = entrypoint.execution_mode.output_vertices;
    const uint32_t num_primitives = entrypoint.execution_mode.output_primitives;
    const bool is_iso_lines = entrypoint.execution_mode.Has(ExecutionModeSet::iso_lines_bit);
    const bool is_point_mode = entrypoint.execution_mode.Has(ExecutionModeSet::point_mode_bit);

    // The max is a combiniation of both the user defined variables largest values
    // and
    // The total components used by built ins
    const auto max_input_slot =
        (entrypoint.max_input_slot_variable && entrypoint.max_input_slot) ? *entrypoint.max_input_slot : InterfaceSlot(0, 0, 0, 0);
    const auto max_output_slot = (entrypoint.max_output_slot_variable && entrypoint.max_output_slot) ? *entrypoint.max_output_slot
                                                                                                     : InterfaceSlot(0, 0, 0, 0);

    const uint32_t total_input_components = max_input_slot.slot + entrypoint.builtin_input_components;
    const uint32_t total_output_components = max_output_slot.slot + entrypoint.builtin_output_components;

    switch (stage) {
        case VK_SHADER_STAGE_VERTEX_BIT:
            if (total_output_components >= limits.maxVertexOutputComponents) {
                skip |= LogError("VUID-RuntimeSpirv-Location-06272", module_state.handle(), loc,
                                 "SPIR-V (Vertex stage) output interface variable (%s) along with %" PRIu32
                                 " built-in components,  "
                                 "exceeds component limit maxVertexOutputComponents (%" PRIu32 ").",
                                 max_output_slot.Describe().c_str(), entrypoint.builtin_output_components,
                                 limits.maxVertexOutputComponents);
            }
            break;

        case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
            if (total_input_components >= limits.maxTessellationControlPerVertexInputComponents) {
                skip |= LogError("VUID-RuntimeSpirv-Location-06272", module_state.handle(), loc,
                                 "SPIR-V (Tessellation control stage) input interface variable (%s) along with %" PRIu32
                                 " built-in components,  "
                                 "exceeds component limit maxTessellationControlPerVertexInputComponents (%" PRIu32 ").",
                                 max_input_slot.Describe().c_str(), entrypoint.builtin_input_components,
                                 limits.maxTessellationControlPerVertexInputComponents);
            }
            if (entrypoint.max_input_slot_variable) {
                if (entrypoint.max_input_slot_variable->is_patch &&
                    total_output_components >= limits.maxTessellationControlPerPatchOutputComponents) {
                    skip |= LogError("VUID-RuntimeSpirv-Location-06272", module_state.handle(), loc,
                                     "SPIR-V (Tessellation control stage) output interface variable (%s) along with %" PRIu32
                                     " built-in components,  "
                                     "exceeds component limit maxTessellationControlPerPatchOutputComponents (%" PRIu32 ").",
                                     max_output_slot.Describe().c_str(), entrypoint.builtin_output_components,
                                     limits.maxTessellationControlPerPatchOutputComponents);
                }
                if (!entrypoint.max_input_slot_variable->is_patch &&
                    total_output_components >= limits.maxTessellationControlPerVertexOutputComponents) {
                    skip |= LogError("VUID-RuntimeSpirv-Location-06272", module_state.handle(), loc,
                                     "SPIR-V (Tessellation control stage) output interface variable (%s) along with %" PRIu32
                                     " built-in components,  "
                                     "exceeds component limit maxTessellationControlPerVertexOutputComponents (%" PRIu32 ").",
                                     max_output_slot.Describe().c_str(), entrypoint.builtin_output_components,
                                     limits.maxTessellationControlPerVertexOutputComponents);
                }
            }
            break;

        case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
            if (total_input_components >= limits.maxTessellationEvaluationInputComponents) {
                skip |= LogError("VUID-RuntimeSpirv-Location-06272", module_state.handle(), loc,
                                 "SPIR-V (Tessellation evaluation stage) input interface variable (%s) along with %" PRIu32
                                 " built-in components,  "
                                 "exceeds component limit maxTessellationEvaluationInputComponents (%" PRIu32 ").",
                                 max_input_slot.Describe().c_str(), entrypoint.builtin_input_components,
                                 limits.maxTessellationEvaluationInputComponents);
            }
            if (total_output_components >= limits.maxTessellationEvaluationOutputComponents) {
                skip |= LogError("VUID-RuntimeSpirv-Location-06272", module_state.handle(), loc,
                                 "SPIR-V (Tessellation evaluation stage) output interface variable (%s) along with %" PRIu32
                                 " built-in components,  "
                                 "exceeds component limit maxTessellationEvaluationOutputComponents (%" PRIu32 ").",
                                 max_output_slot.Describe().c_str(), entrypoint.builtin_output_components,
                                 limits.maxTessellationEvaluationOutputComponents);
            }
            // Portability validation
            if (IsExtEnabled(device_extensions.vk_khr_portability_subset)) {
                if (is_iso_lines && (VK_FALSE == enabled_features.portability_subset_features.tessellationIsolines)) {
                    skip |= LogError("VUID-RuntimeSpirv-tessellationShader-06326", module_state.handle(), loc,
                                     "(portability error) SPIR-V (Tessellation evaluation stage)"
                                     " is using abstract patch type IsoLines, but this is not supported on this platform.");
                }
                if (is_point_mode && (VK_FALSE == enabled_features.portability_subset_features.tessellationPointMode)) {
                    skip |= LogError("VUID-RuntimeSpirv-tessellationShader-06327", module_state.handle(), loc,
                                     "(portability error) SPIR-V (Tessellation evaluation stage)"
                                     " is using abstract patch type PointMode, but this is not supported on this platform.");
                }
            }
            break;

        case VK_SHADER_STAGE_GEOMETRY_BIT:
            if (total_input_components >= limits.maxGeometryInputComponents) {
                skip |= LogError("VUID-RuntimeSpirv-Location-06272", module_state.handle(), loc,
                                 "SPIR-V (Geometry stage) input interface variable (%s) along with %" PRIu32
                                 " built-in components,  "
                                 "exceeds component limit maxGeometryInputComponents (%" PRIu32 ").",
                                 max_input_slot.Describe().c_str(), entrypoint.builtin_input_components,
                                 limits.maxGeometryInputComponents);
            }
            if (total_output_components >= limits.maxGeometryOutputComponents) {
                skip |= LogError("VUID-RuntimeSpirv-Location-06272", module_state.handle(), loc,
                                 "SPIR-V (Geometry stage) output interface variable (%s) along with %" PRIu32
                                 " built-in components,  "
                                 "exceeds component limit maxGeometryOutputComponents (%" PRIu32 ").",
                                 max_output_slot.Describe().c_str(), entrypoint.builtin_output_components,
                                 limits.maxGeometryOutputComponents);
            }
            break;

        case VK_SHADER_STAGE_FRAGMENT_BIT:
            if (total_input_components >= limits.maxFragmentInputComponents) {
                skip |= LogError("VUID-RuntimeSpirv-Location-06272", module_state.handle(), loc,
                                 "SPIR-V (Fragment stage) input interface variable (%s) along with %" PRIu32
                                 " built-in components,  "
                                 "exceeds component limit maxFragmentInputComponents (%" PRIu32 ").",
                                 max_input_slot.Describe().c_str(), entrypoint.builtin_input_components,
                                 limits.maxFragmentInputComponents);
            }
            break;

        case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
        case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
        case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
        case VK_SHADER_STAGE_MISS_BIT_KHR:
        case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
        case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
        case VK_SHADER_STAGE_TASK_BIT_EXT:
            break;

        // Shader stage is an alias, but the ExecutionModel is not
        case VK_SHADER_STAGE_MESH_BIT_EXT:
            if (entrypoint.execution_model == spv::ExecutionModelMeshNV) {
                if (num_vertices > phys_dev_ext_props.mesh_shader_props_nv.maxMeshOutputVertices) {
                    skip |= LogError("VUID-RuntimeSpirv-MeshNV-07113", module_state.handle(), loc,
                                     "SPIR-V (Mesh stage) output vertices count exceeds the "
                                     "maxMeshOutputVertices of %" PRIu32 " by %" PRIu32 ".",
                                     phys_dev_ext_props.mesh_shader_props_nv.maxMeshOutputVertices,
                                     num_vertices - phys_dev_ext_props.mesh_shader_props_nv.maxMeshOutputVertices);
                }
                if (num_primitives > phys_dev_ext_props.mesh_shader_props_nv.maxMeshOutputPrimitives) {
                    skip |= LogError("VUID-RuntimeSpirv-MeshNV-07114", module_state.handle(), loc,
                                     "SPIR-V (Mesh stage) output primitives count exceeds the "
                                     "maxMeshOutputPrimitives of %" PRIu32 " by %" PRIu32 ".",
                                     phys_dev_ext_props.mesh_shader_props_nv.maxMeshOutputPrimitives,
                                     num_primitives - phys_dev_ext_props.mesh_shader_props_nv.maxMeshOutputPrimitives);
                }
            } else if (entrypoint.execution_model == spv::ExecutionModelMeshEXT) {
                if (num_vertices > phys_dev_ext_props.mesh_shader_props_ext.maxMeshOutputVertices) {
                    skip |= LogError("VUID-RuntimeSpirv-MeshEXT-07115", module_state.handle(), loc,
                                     "SPIR-V (Mesh stage) output vertices count exceeds the "
                                     "maxMeshOutputVertices of %" PRIu32 " by %" PRIu32 ".",
                                     phys_dev_ext_props.mesh_shader_props_ext.maxMeshOutputVertices,
                                     num_vertices - phys_dev_ext_props.mesh_shader_props_ext.maxMeshOutputVertices);
                }
                if (num_primitives > phys_dev_ext_props.mesh_shader_props_ext.maxMeshOutputPrimitives) {
                    skip |= LogError("VUID-RuntimeSpirv-MeshEXT-07116", module_state.handle(), loc,
                                     "SPIR-V (Mesh stage) output primitives count exceeds the "
                                     "maxMeshOutputPrimitives of %" PRIu32 " by %" PRIu32 ".",
                                     phys_dev_ext_props.mesh_shader_props_ext.maxMeshOutputPrimitives,
                                     num_primitives - phys_dev_ext_props.mesh_shader_props_ext.maxMeshOutputPrimitives);
                }
            }
            break;

        default:
            assert(false);  // This should never happen
    }
    return skip;
}

bool CoreChecks::ValidateInterfaceBetweenStages(const SPIRV_MODULE_STATE &producer, const EntryPoint &producer_entrypoint,
                                                const SPIRV_MODULE_STATE &consumer, const EntryPoint &consumer_entrypoint,
                                                const Location &create_info_loc) const {
    bool skip = false;

    if (producer_entrypoint.has_passthrough) {
        return skip;  // PassthroughNV doesn't have to do Location matching
    }

    const VkShaderStageFlagBits producer_stage = producer_entrypoint.stage;
    const VkShaderStageFlagBits consumer_stage = consumer_entrypoint.stage;

    // build up a mapping of which slots are used and then go through it and look for gaps
    struct ComponentInfo {
        const StageInteraceVariable *output = nullptr;
        uint32_t output_type = 0;
        uint32_t output_width = 0;
        const StageInteraceVariable *input = nullptr;
        uint32_t input_type = 0;
        uint32_t input_width = 0;
    };
    // <Location, Components[4]> (only 4 components in a Location)
    vvl::unordered_map<uint32_t, std::array<ComponentInfo, 4>> slot_map;

    for (const auto &interface_slot : producer_entrypoint.output_interface_slots) {
        auto &slot = slot_map[interface_slot.first.Location()][interface_slot.first.Component()];
        if (interface_slot.second->nested_struct || interface_slot.second->physical_storage_buffer) {
            return skip;  // TODO workaround
        }
        slot.output = interface_slot.second;
        slot.output_type = interface_slot.first.type;
        slot.output_width = interface_slot.first.bit_width;
    }
    for (const auto &interface_slot : consumer_entrypoint.input_interface_slots) {
        auto &slot = slot_map[interface_slot.first.Location()][interface_slot.first.Component()];
        if (interface_slot.second->nested_struct || interface_slot.second->physical_storage_buffer) {
            return skip;  // TODO workaround
        }
        slot.input = interface_slot.second;
        slot.input_type = interface_slot.first.type;
        slot.input_width = interface_slot.first.bit_width;
    }

    for (const auto &slot : slot_map) {
        // Found that sometimes there is a big mismatch and printing out EVERY slot adds a lot of noise
        if (skip) break;

        const uint32_t location = slot.first;
        for (uint32_t component = 0; component < 4; component++) {
            const auto &component_info = slot.second[component];
            const auto *input_var = component_info.input;
            const auto *output_var = component_info.output;

            if ((input_var == nullptr) && (output_var == nullptr)) {
                continue;  // both empty
            } else if ((input_var != nullptr) && (output_var != nullptr)) {
                // if matched, need to check type
                // Only the OpType has to match, signed vs unsigned in not important
                if ((component_info.output_type != component_info.input_type) ||
                    (component_info.output_width != component_info.input_width)) {
                    const LogObjectList objlist(producer.handle(), consumer.handle());
                    skip |=
                        LogError("VUID-RuntimeSpirv-OpEntryPoint-07754", objlist, create_info_loc,
                                 "(SPIR-V Interface) Type mismatch on Location %" PRIu32 " Component %" PRIu32
                                 ", between\n%s stage:\n%s\n%s stage:\n%s\n",
                                 location, component, string_VkShaderStageFlagBits(producer_stage),
                                 producer.DescribeType(output_var->type_id).c_str(), string_VkShaderStageFlagBits(consumer_stage),
                                 consumer.DescribeType(input_var->type_id).c_str());
                }

                // Tessellation needs to match Patch vs Vertex
                if ((producer_stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) &&
                    (consumer_stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) &&
                    (input_var->is_patch != output_var->is_patch)) {
                    const LogObjectList objlist(producer.handle(), consumer.handle());
                    skip |= LogError("VUID-RuntimeSpirv-OpVariable-08746", objlist, create_info_loc,
                                     "(SPIR-V Interface) at Location %" PRIu32 " Component %" PRIu32
                                     " Tessellation Control is %s while Tessellation Evaluation is %s",
                                     location, component, input_var->is_patch ? "patch" : "vertex",
                                     output_var->is_patch ? "patch" : "vertex");
                }

                // If using maintenance4 need to check Vectors incase different sizes
                if (!enabled_features.core13.maintenance4 && (output_var->base_type.Opcode() == spv::OpTypeVector) &&
                    (input_var->base_type.Opcode() == spv::OpTypeVector)) {
                    // Note the "Component Count" in the VU refers to OpTypeVector's operand and NOT the "Component slot"
                    const uint32_t output_vec_size = output_var->base_type.Word(3);
                    const uint32_t input_vec_size = input_var->base_type.Word(3);
                    if (output_vec_size > input_vec_size) {
                        const LogObjectList objlist(producer.handle(), consumer.handle());
                        skip |= LogError("VUID-RuntimeSpirv-maintenance4-06817", objlist, create_info_loc,
                                         "(SPIR-V Interface) starting at Location %" PRIu32 " Component %" PRIu32
                                         " the Output (%s) has a Vec%" PRIu32 " while Input (%s) as a Vec%" PRIu32
                                         ". Enable VK_KHR_maintenance4 device extension to allow relaxed interface matching "
                                         "between input and output vectors.",
                                         location, component, string_VkShaderStageFlagBits(producer_stage), output_vec_size,
                                         string_VkShaderStageFlagBits(consumer_stage), input_vec_size);
                        break;  // Only need to report for the first component found
                    }
                }
            } else if ((input_var == nullptr) && (output_var != nullptr)) {
                // Missing input slot
                // It is not an error if a stage does not consume all outputs from the previous stage
                // The values will be undefined, but still legal
                // Don't give any warning if maintenance4 with vectors
                if (!enabled_features.core13.maintenance4 && (output_var->base_type.Opcode() != spv::OpTypeVector)) {
                    const LogObjectList objlist(producer.handle(), consumer.handle());
                    skip |= LogPerformanceWarning(kVUID_Core_Shader_OutputNotConsumed, objlist, create_info_loc,
                                                  "(SPIR-V Interface) %s declared to output location %" PRIu32 " Component %" PRIu32
                                                  " but is not an Input declared by %s.",
                                                  string_VkShaderStageFlagBits(producer_stage), location, component,
                                                  string_VkShaderStageFlagBits(consumer_stage));
                }
            } else if ((input_var != nullptr) && (output_var == nullptr)) {
                // Missing output slot
                if ((consumer_stage & (VK_SHADER_STAGE_GEOMETRY_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT |
                                       VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)) &&
                    (input_var->base_type.Opcode() == spv::OpTypeArray)) {
                    break;  // When going inbetween Tessellation or Geometry, array size can be different
                }
                const LogObjectList objlist(producer.handle(), consumer.handle());
                skip |= LogError("VUID-RuntimeSpirv-OpEntryPoint-08743", objlist, create_info_loc,
                                 "(SPIR-V Interface) %s declared input at Location %" PRIu32 " Component %" PRIu32
                                 " but it is not an Output declared in %s",
                                 string_VkShaderStageFlagBits(consumer_stage), location, component,
                                 string_VkShaderStageFlagBits(producer_stage));
                break;  // Only need to report for the first component found
            }
        }
    }

    // Need to check the BuiltIn interface (if not going into Fragment)
    if (consumer_stage == VK_SHADER_STAGE_FRAGMENT_BIT) {
        return skip;
    }

    std::vector<uint32_t> input_builtins_block;
    std::vector<uint32_t> output_builtins_block;
    for (const auto *variable : producer_entrypoint.built_in_variables) {
        if (variable->storage_class == spv::StorageClassOutput && !variable->builtin_block.empty()) {
            output_builtins_block = variable->builtin_block;
            break;
        }
    }
    for (const auto *variable : consumer_entrypoint.built_in_variables) {
        if (variable->storage_class == spv::StorageClassInput && !variable->builtin_block.empty()) {
            input_builtins_block = variable->builtin_block;
            break;
        }
    }

    bool mismatch = false;
    if (input_builtins_block.empty() || output_builtins_block.empty()) {
        // TODO - Nothing about this in spec, need to add language to confirm this is correct
        return skip;
    } else if (input_builtins_block.size() != output_builtins_block.size()) {
        mismatch = true;
    } else {
        for (size_t i = 0; i < input_builtins_block.size(); i++) {
            const uint32_t input_builtin = input_builtins_block[i];
            const uint32_t output_builtin = output_builtins_block[i];
            if (input_builtin == kInvalidSpirvValue || output_builtin == kInvalidSpirvValue) {
                continue;  // some stages (TessControl -> TessEval) can have legal block vs non-block mistmatch
            } else if (input_builtin != output_builtin) {
                mismatch = true;
            }
        }
    }

    if (mismatch) {
        std::stringstream msg;
        msg << string_VkShaderStageFlagBits(producer_stage) << " Output Block {\n";
        for (size_t i = 0; i < output_builtins_block.size(); i++) {
            msg << "\t" << i << ": " << string_SpvBuiltIn(output_builtins_block[i]) << "\n";
        }
        msg << "}\n";
        msg << string_VkShaderStageFlagBits(consumer_stage) << " Input Block {\n";
        for (size_t i = 0; i < input_builtins_block.size(); i++) {
            msg << "\t" << i << ": " << string_SpvBuiltIn(input_builtins_block[i]) << "\n";
        }
        msg << "}\n";
        const LogObjectList objlist(producer.handle(), consumer.handle());
        skip |= LogError("VUID-RuntimeSpirv-OpVariable-08746", objlist, create_info_loc,
                         "(SPIR-V Interface) Mistmatch in BuiltIn blocks:\n %s", msg.str().c_str());
    }
    return skip;
}

// Validate that the shaders used by the given pipeline and store the active_slots
//  that are actually used by the pipeline into pPipeline->active_slots
bool CoreChecks::ValidateGraphicsPipelineShaderState(const PIPELINE_STATE &pipeline, const Location &create_info_loc) const {
    bool skip = false;

    if (!(pipeline.pre_raster_state || pipeline.fragment_shader_state)) {
        // Only validate pipelines that contain shader stages
        return skip;
    }

    const PipelineStageState *vertex_stage = nullptr, *fragment_stage = nullptr;
    for (uint32_t i = 0; i < pipeline.stage_states.size(); i++) {
        auto &stage_state = pipeline.stage_states[i];
        const VkShaderStageFlagBits stage = stage_state.GetStage();
        // Only validate the shader state once when added, not again when linked
        if ((stage & pipeline.linking_shaders) == 0) {
            StageCreateInfo stage_create_info(&pipeline);
            skip |= ValidatePipelineShaderStage(stage_create_info, stage_state, create_info_loc.dot(Field::pStages, i));
        }
        if (stage == VK_SHADER_STAGE_VERTEX_BIT) {
            vertex_stage = &stage_state;
        }
        if (stage == VK_SHADER_STAGE_FRAGMENT_BIT) {
            fragment_stage = &stage_state;
        }
    }

    // if the shader stages are no good individually, cross-stage validation is pointless.
    if (skip) return true;

    if (pipeline.vertex_input_state && vertex_stage && vertex_stage->entrypoint && vertex_stage->spirv_state &&
        !pipeline.IsDynamic(VK_DYNAMIC_STATE_VERTEX_INPUT_EXT)) {
        skip |=
            ValidateInterfaceVertexInput(pipeline, *vertex_stage->spirv_state.get(), *vertex_stage->entrypoint, create_info_loc);
    }

    if (pipeline.fragment_shader_state && fragment_stage && fragment_stage->entrypoint && fragment_stage->spirv_state) {
        skip |= ValidateInterfaceFragmentOutput(pipeline, *fragment_stage->spirv_state.get(), *fragment_stage->entrypoint,
                                                create_info_loc);
    }

    for (size_t i = 1; i < pipeline.stage_states.size(); i++) {
        const auto &producer = pipeline.stage_states[i - 1];
        const auto &consumer = pipeline.stage_states[i];
        const std::shared_ptr<const SPIRV_MODULE_STATE> &producer_spirv =
            producer.spirv_state ? producer.spirv_state : producer.module_state->spirv;
        const std::shared_ptr<const SPIRV_MODULE_STATE> &consumer_spirv =
            consumer.spirv_state ? consumer.spirv_state : consumer.module_state->spirv;
        assert(producer.module_state);
        if (&producer == fragment_stage) {
            break;
        }
        if (consumer_spirv && producer_spirv && consumer.entrypoint && producer.entrypoint) {
            skip |= ValidateInterfaceBetweenStages(*producer_spirv.get(), *producer.entrypoint, *consumer_spirv.get(),
                                                   *consumer.entrypoint, create_info_loc);
        }
    }
    return skip;
}
