/* Copyright (c) 2018-2025 The Khronos Group Inc.
 * Copyright (c) 2018-2025 Valve Corporation
 * Copyright (c) 2018-2025 LunarG, 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 "gpu/cmd_validation/gpuav_draw.h"

#include "gpu/core/gpuav.h"
#include "gpu/cmd_validation/gpuav_cmd_validation_common.h"
#include "gpu/error_message/gpuav_vuids.h"
#include "gpu/resources/gpuav_vulkan_objects.h"
#include "gpu/resources/gpuav_state_trackers.h"
#include "gpu/shaders/gpuav_error_header.h"
#include "gpu/shaders/gpuav_shaders_constants.h"

#include "state_tracker/render_pass_state.h"
#include "gpu/shaders/gpuav_error_header.h"
#include "gpu/shaders/gpuav_shaders_constants.h"
#include "gpu/shaders/cmd_validation/draw_push_data.h"
#include "generated/cmd_validation_draw_mesh_indirect_comp.h"
#include "generated/cmd_validation_first_instance_comp.h"
#include "generated/cmd_validation_count_buffer_comp.h"
#include "generated/cmd_validation_draw_indexed_comp.h"
#include "generated/cmd_validation_draw_indexed_indirect_index_buffer_comp.h"
#include "generated/cmd_validation_draw_indexed_indirect_vertex_buffer_comp.h"

#include "profiling/profiling.h"

#include <optional>

namespace gpuav {
namespace valcmd {

struct SharedDrawValidationResources {
    vko::Buffer dummy_buffer;  // Used to fill unused buffer bindings in validation pipelines
    bool valid = false;

    SharedDrawValidationResources(Validator &gpuav, const Location &loc) : dummy_buffer(gpuav) {
        VkBufferCreateInfo dummy_buffer_info = vku::InitStructHelper();
        dummy_buffer_info.size = 64;// whatever
        dummy_buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
        VmaAllocationCreateInfo alloc_info = {};
        dummy_buffer_info.size = dummy_buffer_info.size;
        const bool success = dummy_buffer.Create(loc, &dummy_buffer_info, &alloc_info);
        if (!success) {
            valid = false;
            return;
        }

        valid = true;
    }

    ~SharedDrawValidationResources() { dummy_buffer.Destroy(); }
};

struct BoundStorageBuffer {
    uint32_t binding = vvl::kU32Max;
    VkDescriptorBufferInfo info{VK_NULL_HANDLE, vvl::kU64Max, 0};
};

template <typename ShaderResources>
struct ComputeValidationPipeline {
    ComputeValidationPipeline(Validator &gpuav, const Location &loc, VkDescriptorSetLayout error_output_desc_set_layout) {
        std::vector<VkDescriptorSetLayoutBinding> specific_bindings = ShaderResources::GetDescriptorSetLayoutBindings();

        VkPushConstantRange push_constant_range = {};
        push_constant_range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
        push_constant_range.offset = 0;
        push_constant_range.size = sizeof(ShaderResources::push_constants);  // 0 size is ok here

        device = gpuav.device;
        VkDescriptorSetLayoutCreateInfo ds_layout_ci = vku::InitStructHelper();

        ds_layout_ci.bindingCount = static_cast<uint32_t>(specific_bindings.size());
        ds_layout_ci.pBindings = specific_bindings.data();
        VkResult result = DispatchCreateDescriptorSetLayout(device, &ds_layout_ci, nullptr, &specific_desc_set_layout);
        if (result != VK_SUCCESS) {
            gpuav.InternalError(device, loc, "Unable to create descriptor set layout for SharedDrawValidationResources.");
            return;
        }

        std::array<VkDescriptorSetLayout, 2> set_layouts = {{error_output_desc_set_layout, specific_desc_set_layout}};
        VkPipelineLayoutCreateInfo pipeline_layout_ci = vku::InitStructHelper();
        if (push_constant_range.size > 0) {
            pipeline_layout_ci.pushConstantRangeCount = 1;
            pipeline_layout_ci.pPushConstantRanges = &push_constant_range;
        }
        pipeline_layout_ci.setLayoutCount = static_cast<uint32_t>(set_layouts.size());
        pipeline_layout_ci.pSetLayouts = set_layouts.data();
        result = DispatchCreatePipelineLayout(device, &pipeline_layout_ci, nullptr, &pipeline_layout);
        if (result != VK_SUCCESS) {
            gpuav.InternalError(device, loc, "Unable to create pipeline layout for SharedDrawValidationResources.");
            return;
        }

        VkShaderModuleCreateInfo shader_module_ci = vku::InitStructHelper();
        shader_module_ci.codeSize = ShaderResources::GetSpirvSize();
        shader_module_ci.pCode = ShaderResources::GetSpirv();
        result = DispatchCreateShaderModule(device, &shader_module_ci, nullptr, &shader_module);
        if (result != VK_SUCCESS) {
            gpuav.InternalError(device, loc, "Unable to create shader module.");
            return;
        }

        VkComputePipelineCreateInfo compute_validation_pipeline_ci = vku::InitStructHelper();
        compute_validation_pipeline_ci.stage = vku::InitStructHelper();
        compute_validation_pipeline_ci.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
        compute_validation_pipeline_ci.stage.module = shader_module;
        compute_validation_pipeline_ci.stage.pName = "main";
        compute_validation_pipeline_ci.layout = pipeline_layout;
        result = DispatchCreateComputePipelines(device, VK_NULL_HANDLE, 1, &compute_validation_pipeline_ci, nullptr, &pipeline);
        if (result != VK_SUCCESS) {
            gpuav.InternalError(device, loc, "Unable to create compute validation pipeline.");
            return;
        }

        valid = true;
    }

    ~ComputeValidationPipeline() {
        if (pipeline != VK_NULL_HANDLE) {
            DispatchDestroyPipeline(device, pipeline, nullptr);
        }

        if (shader_module != VK_NULL_HANDLE) {
            DispatchDestroyShaderModule(device, shader_module, nullptr);
        }

        if (specific_desc_set_layout != VK_NULL_HANDLE) {
            DispatchDestroyDescriptorSetLayout(device, specific_desc_set_layout, nullptr);
        }

        if (pipeline_layout != VK_NULL_HANDLE) {
            DispatchDestroyPipelineLayout(device, pipeline_layout, nullptr);
        }
    }

    void BindShaderResources(Validator &gpuav, CommandBuffer &cb_state, uint32_t cmd_index, uint32_t error_logger_index,
                             const ShaderResources &shader_resources) {
        // Error logging resources
        BindErrorLoggingDescSet(gpuav, cb_state, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_layout, cmd_index, error_logger_index);

        // Specific resources
        VkDescriptorSet desc_set = cb_state.gpu_resources_manager.GetManagedDescriptorSet(specific_desc_set_layout);
        std::vector<VkWriteDescriptorSet> desc_writes = shader_resources.GetDescriptorWrites(desc_set);
        DispatchUpdateDescriptorSets(gpuav.device, uint32_t(desc_writes.size()), desc_writes.data(), 0, nullptr);

        DispatchCmdPushConstants(cb_state.VkHandle(), pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 0,
                                 sizeof(shader_resources.push_constants), &shader_resources.push_constants);

        DispatchCmdBindDescriptorSets(cb_state.VkHandle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_layout,
                                      shader_resources.desc_set_id, 1, &desc_set, 0, nullptr);
    }

    VkDevice device = VK_NULL_HANDLE;
    VkDescriptorSetLayout specific_desc_set_layout = VK_NULL_HANDLE;
    VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
    VkShaderModule shader_module = VK_NULL_HANDLE;
    VkPipeline pipeline = VK_NULL_HANDLE;
    bool valid = false;
};

void FlushValidationCmds(Validator &gpuav, CommandBuffer &cb_state) {
    VVL_TracyPlot("gpuav::valcmd::FlushValidationCmds", int64_t(cb_state.per_render_pass_validation_commands.size()));
    VVL_ZoneScoped;
    RestorablePipelineState restorable_state(cb_state, VK_PIPELINE_BIND_POINT_COMPUTE);

    for (CommandBuffer::ValidationCommandFunc &validation_cmd : cb_state.per_render_pass_validation_commands) {
        validation_cmd(gpuav, cb_state);
    }
    cb_state.per_render_pass_validation_commands.clear();
}

struct FirstInstanceValidationShader {
    static size_t GetSpirvSize() { return cmd_validation_first_instance_comp_size * sizeof(uint32_t); }
    static const uint32_t *GetSpirv() { return cmd_validation_first_instance_comp; }

    static const uint32_t desc_set_id = gpuav::glsl::kDiagPerCmdDescriptorSet;

    glsl::FirstInstancePushData push_constants{};
    BoundStorageBuffer draw_buffer_binding = {gpuav::glsl::kPreDrawBinding_IndirectBuffer};
    BoundStorageBuffer count_buffer_binding = {gpuav::glsl::kPreDrawBinding_CountBuffer};

    static std::vector<VkDescriptorSetLayoutBinding> GetDescriptorSetLayoutBindings() {
        std::vector<VkDescriptorSetLayoutBinding> bindings = {
            {gpuav::glsl::kPreDrawBinding_IndirectBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT,
             nullptr},  // indirect buffer
            {gpuav::glsl::kPreDrawBinding_CountBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT,
             nullptr},  // count buffer
        };

        return bindings;
    }

    std::vector<VkWriteDescriptorSet> GetDescriptorWrites(VkDescriptorSet desc_set) const {
        std::vector<VkWriteDescriptorSet> desc_writes(2);

        desc_writes[0] = vku::InitStructHelper();
        desc_writes[0].dstSet = desc_set;
        desc_writes[0].dstBinding = draw_buffer_binding.binding;
        desc_writes[0].dstArrayElement = 0;
        desc_writes[0].descriptorCount = 1;
        desc_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
        desc_writes[0].pBufferInfo = &draw_buffer_binding.info;

        desc_writes[1] = vku::InitStructHelper();
        desc_writes[1].dstSet = desc_set;
        desc_writes[1].dstBinding = count_buffer_binding.binding;
        desc_writes[1].dstArrayElement = 0;
        desc_writes[1].descriptorCount = 1;
        desc_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
        desc_writes[1].pBufferInfo = &count_buffer_binding.info;

        return desc_writes;
    }
};

void FirstInstance(Validator &gpuav, CommandBuffer &cb_state, const Location &loc, VkBuffer draw_buffer,
                   VkDeviceSize draw_buffer_offset, uint32_t draw_cmds_byte_stride, vvl::Struct draw_indirect_struct_name,
                   uint32_t first_instance_member_pos, uint32_t draw_count, VkBuffer count_buffer, VkDeviceSize count_buffer_offset,
                   const char *vuid) {
    if (!gpuav.gpuav_settings.validate_indirect_draws_buffers) {
        return;
    }

    if (gpuav.enabled_features.drawIndirectFirstInstance) return;

    CommandBuffer::ValidationCommandFunc validation_cmd = [draw_buffer, draw_buffer_offset, draw_cmds_byte_stride,
                                                           first_instance_member_pos, draw_count, count_buffer, count_buffer_offset,
                                                           draw_i = cb_state.draw_index,
                                                           error_logger_i = uint32_t(cb_state.per_command_error_loggers.size()),
                                                           loc](Validator &gpuav, CommandBuffer &cb_state) {
        SharedDrawValidationResources &shared_draw_validation_resources =
            gpuav.shared_resources_manager.Get<SharedDrawValidationResources>(gpuav, loc);
        if (!shared_draw_validation_resources.valid) return;
        ComputeValidationPipeline<FirstInstanceValidationShader> &validation_pipeline =
            gpuav.shared_resources_manager.Get<ComputeValidationPipeline<FirstInstanceValidationShader>>(
                gpuav, loc, cb_state.GetErrorLoggingDescSetLayout());
        if (!validation_pipeline.valid) return;

        auto draw_buffer_state = gpuav.Get<vvl::Buffer>(draw_buffer);
        if (!draw_buffer_state) {
            gpuav.InternalError(LogObjectList(cb_state.VkHandle(), draw_buffer), loc, "buffer must be a valid VkBuffer handle");
            return;
        }

        // Setup shader resources
        // ---
        {
            FirstInstanceValidationShader shader_resources;
            shader_resources.push_constants.draw_cmds_stride_dwords = draw_cmds_byte_stride / sizeof(uint32_t);
            shader_resources.push_constants.cpu_draw_count = draw_count;
            shader_resources.push_constants.first_instance_member_pos = first_instance_member_pos;

            shader_resources.draw_buffer_binding.info = {draw_buffer, 0, VK_WHOLE_SIZE};
            shader_resources.push_constants.draw_buffer_dwords_offset = (uint32_t)draw_buffer_offset / sizeof(uint32_t);
            if (count_buffer) {
                shader_resources.push_constants.flags |= gpuav::glsl::kFirstInstanceFlags_DrawCountFromBuffer;
                shader_resources.count_buffer_binding.info = {count_buffer, 0, sizeof(uint32_t)};
                shader_resources.push_constants.count_buffer_dwords_offset = (uint32_t)count_buffer_offset / sizeof(uint32_t);

            } else {
                shader_resources.count_buffer_binding.info = {shared_draw_validation_resources.dummy_buffer.VkHandle(), 0,
                                                              VK_WHOLE_SIZE};
            }

            validation_pipeline.BindShaderResources(gpuav, cb_state, draw_i, error_logger_i, shader_resources);
        }

        // Setup validation pipeline
        // ---
        {
            DispatchCmdBindPipeline(cb_state.VkHandle(), VK_PIPELINE_BIND_POINT_COMPUTE, validation_pipeline.pipeline);

            uint32_t max_held_draw_cmds = 0;
            if (draw_buffer_state->create_info.size > draw_buffer_offset) {
                // If drawCount is less than or equal to one, stride is ignored
                if (draw_count > 1) {
                    max_held_draw_cmds =
                        static_cast<uint32_t>((draw_buffer_state->create_info.size - draw_buffer_offset) / draw_cmds_byte_stride);
                } else {
                    max_held_draw_cmds = 1;
                }
            }
            // It is assumed that the number of draws to validate is fairly low.
            // Otherwise might reconsider having a warp dimension of (1, 1, 1)
            // Maybe another reason to add telemetry?
            const uint32_t work_group_count = std::min(draw_count, max_held_draw_cmds);

            if (work_group_count == 0) {
                return;
            }

            VVL_TracyPlot("gpuav::valcmd::FirstInstance Dispatch size", int64_t(work_group_count));
            DispatchCmdDispatch(cb_state.VkHandle(), work_group_count, 1, 1);

            // synchronize draw buffer validation (read) against subsequent writes
            std::array<VkBufferMemoryBarrier, 2> buffer_memory_barriers = {};
            uint32_t buffer_memory_barriers_count = 1;
            buffer_memory_barriers[0] = vku::InitStructHelper();
            buffer_memory_barriers[0].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
            buffer_memory_barriers[0].dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
            buffer_memory_barriers[0].buffer = draw_buffer;
            buffer_memory_barriers[0].offset = draw_buffer_offset;
            buffer_memory_barriers[0].size = work_group_count * sizeof(uint32_t);

            if (count_buffer) {
                buffer_memory_barriers[1] = vku::InitStructHelper();
                buffer_memory_barriers[1].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
                buffer_memory_barriers[1].dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
                buffer_memory_barriers[1].buffer = count_buffer;
                buffer_memory_barriers[1].offset = count_buffer_offset;
                buffer_memory_barriers[1].size = sizeof(uint32_t);
                ++buffer_memory_barriers_count;
            }

            DispatchCmdPipelineBarrier(cb_state.VkHandle(), VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
                                       VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, buffer_memory_barriers_count,
                                       buffer_memory_barriers.data(), 0, nullptr);
        }
    };

    cb_state.per_render_pass_validation_commands.emplace_back(std::move(validation_cmd));

    // Register error logger. Happens per command GPU-AV intercepts
    // ---
    const uint32_t label_command_i =
        !cb_state.GetLabelCommands().empty() ? uint32_t(cb_state.GetLabelCommands().size() - 1) : vvl::kU32Max;
    CommandBuffer::ErrorLoggerFunc error_logger =
        [loc, vuid, draw_indirect_struct_name, label_command_i](Validator &gpuav, const CommandBuffer &cb_state,
                                                                const uint32_t *error_record, const LogObjectList &objlist,
                                                                const std::vector<std::string> &initial_label_stack) {
            bool skip = false;

            using namespace glsl;

            if (error_record[kHeaderErrorGroupOffset] != kErrorGroupGpuPreDraw) {
                assert(false);
                return skip;
            }

            assert(error_record[kHeaderErrorSubCodeOffset] == kErrorSubCodePreDrawFirstInstance);

            const uint32_t index = error_record[kPreActionParamOffset_0];
            const uint32_t invalid_first_instance = error_record[kPreActionParamOffset_1];

            std::string debug_region_name = cb_state.GetDebugLabelRegion(label_command_i, initial_label_stack);
            Location loc_with_debug_region(loc, debug_region_name);
            skip |= gpuav.LogError(
                vuid, objlist, loc_with_debug_region,
                "The drawIndirectFirstInstance feature is not enabled, but the firstInstance member of the %s structure at "
                "index %" PRIu32 " is %" PRIu32 ".",
                vvl::String(draw_indirect_struct_name), index, invalid_first_instance);

            return skip;
        };

    cb_state.per_command_error_loggers.emplace_back(std::move(error_logger));
}

template <>
void FirstInstance<VkDrawIndirectCommand>(Validator &gpuav, CommandBuffer &cb_state, const Location &loc, VkBuffer draw_buffer,
                                          VkDeviceSize draw_buffer_offset, uint32_t draw_count, VkBuffer count_buffer,
                                          VkDeviceSize count_buffer_offset, const char *vuid) {
    FirstInstance(gpuav, cb_state, loc, draw_buffer, draw_buffer_offset, sizeof(VkDrawIndirectCommand), vvl::Struct::VkDrawIndirectCommand, 3,
                  draw_count, count_buffer, count_buffer_offset, vuid);
}

template <>
void FirstInstance<VkDrawIndexedIndirectCommand>(Validator &gpuav, CommandBuffer &cb_state, const Location &loc,
                                                 VkBuffer draw_buffer, VkDeviceSize draw_buffer_offset, uint32_t draw_count,
                                                 VkBuffer count_buffer, VkDeviceSize count_buffer_offset, const char *vuid) {
    FirstInstance(gpuav, cb_state, loc, draw_buffer, draw_buffer_offset, sizeof(VkDrawIndexedIndirectCommand),
                  vvl::Struct::VkDrawIndexedIndirectCommand, 4, draw_count, count_buffer, count_buffer_offset, vuid);
}

struct CountBufferValidationShader {
    static size_t GetSpirvSize() { return cmd_validation_count_buffer_comp_size * sizeof(uint32_t); }
    static const uint32_t *GetSpirv() { return cmd_validation_count_buffer_comp; }

    static const uint32_t desc_set_id = gpuav::glsl::kDiagPerCmdDescriptorSet;

    glsl::CountBufferPushData push_constants{};
    BoundStorageBuffer count_buffer_binding = {gpuav::glsl::kPreDrawBinding_CountBuffer};

    static std::vector<VkDescriptorSetLayoutBinding> GetDescriptorSetLayoutBindings() {
        std::vector<VkDescriptorSetLayoutBinding> bindings = {
            {gpuav::glsl::kPreDrawBinding_CountBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT,
             nullptr},  // count buffer
        };

        return bindings;
    }

    std::vector<VkWriteDescriptorSet> GetDescriptorWrites(VkDescriptorSet desc_set) const {
        std::vector<VkWriteDescriptorSet> desc_writes(1);

        desc_writes[0] = vku::InitStructHelper();
        desc_writes[0].dstSet = desc_set;
        desc_writes[0].dstBinding = count_buffer_binding.binding;
        desc_writes[0].dstArrayElement = 0;
        desc_writes[0].descriptorCount = 1;
        desc_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
        desc_writes[0].pBufferInfo = &count_buffer_binding.info;

        return desc_writes;
    }
};

void CountBuffer(Validator &gpuav, CommandBuffer &cb_state, const Location &loc, VkBuffer draw_buffer,
                 VkDeviceSize draw_buffer_offset, uint32_t draw_indirect_struct_byte_size, vvl::Struct draw_indirect_struct_name,
                 uint32_t draw_cmds_byte_stride, VkBuffer count_buffer, VkDeviceSize count_buffer_offset,
                 const char *vuid_max_draw_count) {
    if (!gpuav.gpuav_settings.validate_indirect_draws_buffers) {
        return;
    }

    if (!gpuav.enabled_features.shaderInt64) {
        return;
    }

    auto draw_buffer_state = gpuav.Get<vvl::Buffer>(draw_buffer);
    if (!draw_buffer_state) {
        gpuav.InternalError(LogObjectList(cb_state.VkHandle(), draw_buffer), loc, "buffer must be a valid VkBuffer handle");
        return;
    }

    CommandBuffer::ValidationCommandFunc validation_cmd = [draw_buffer_size = draw_buffer_state->create_info.size,
                                                           draw_buffer_offset, draw_indirect_struct_byte_size,
                                                           draw_cmds_byte_stride, count_buffer, count_buffer_offset,
                                                           draw_i = cb_state.draw_index,
                                                           error_logger_i = uint32_t(cb_state.per_command_error_loggers.size()),
                                                           loc](Validator &gpuav, CommandBuffer &cb_state) {
        SharedDrawValidationResources &shared_draw_validation_resources =
            gpuav.shared_resources_manager.Get<SharedDrawValidationResources>(gpuav, loc);
        if (!shared_draw_validation_resources.valid) return;
        ComputeValidationPipeline<CountBufferValidationShader> &validation_pipeline =
            gpuav.shared_resources_manager.Get<ComputeValidationPipeline<CountBufferValidationShader>>(
                gpuav, loc, cb_state.GetErrorLoggingDescSetLayout());
        if (!validation_pipeline.valid) return;

        // Setup shader resources
        // ---
        {
            CountBufferValidationShader shader_resources;
            shader_resources.push_constants.draw_cmds_byte_stride = draw_cmds_byte_stride;
            shader_resources.push_constants.draw_buffer_offset = draw_buffer_offset;
            shader_resources.push_constants.draw_buffer_size = draw_buffer_size;
            shader_resources.push_constants.draw_cmd_byte_size = draw_indirect_struct_byte_size;
            shader_resources.push_constants.device_limit_max_draw_indirect_count = gpuav.phys_dev_props.limits.maxDrawIndirectCount;

            shader_resources.count_buffer_binding.info = {count_buffer, 0, sizeof(uint32_t)};
            shader_resources.push_constants.count_buffer_dwords_offset = (uint32_t)count_buffer_offset / sizeof(uint32_t);

            validation_pipeline.BindShaderResources(gpuav, cb_state, draw_i, error_logger_i, shader_resources);
        }

        // Setup validation pipeline
        // ---
        {
            DispatchCmdBindPipeline(cb_state.VkHandle(), VK_PIPELINE_BIND_POINT_COMPUTE, validation_pipeline.pipeline);
            DispatchCmdDispatch(cb_state.VkHandle(), 1, 1, 1);
            // synchronize draw buffer validation (read) against subsequent writes
            VkBufferMemoryBarrier count_buffer_memory_barrier = vku::InitStructHelper();
            count_buffer_memory_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
            count_buffer_memory_barrier.dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
            count_buffer_memory_barrier.buffer = count_buffer;
            count_buffer_memory_barrier.offset = count_buffer_offset;
            count_buffer_memory_barrier.size = sizeof(uint32_t);

            DispatchCmdPipelineBarrier(cb_state.VkHandle(), VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
                                       VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 1, &count_buffer_memory_barrier, 0,
                                       nullptr);
        }
    };

    cb_state.per_render_pass_validation_commands.emplace_back(std::move(validation_cmd));

    // Register error logger
    // ---
    const uint32_t label_command_i =
        !cb_state.GetLabelCommands().empty() ? uint32_t(cb_state.GetLabelCommands().size() - 1) : vvl::kU32Max;
    CommandBuffer::ErrorLoggerFunc error_logger = [loc, draw_buffer, draw_buffer_size = draw_buffer_state->create_info.size,
                                                   draw_buffer_offset, draw_indirect_struct_byte_size, draw_cmds_byte_stride,
                                                   draw_indirect_struct_name, vuid_max_draw_count,
                                                   label_command_i](Validator &gpuav, const CommandBuffer &cb_state,
                                                                    const uint32_t *error_record, const LogObjectList &objlist,
                                                                    const std::vector<std::string> &initial_label_stack) {
        bool skip = false;

        using namespace glsl;

        std::string debug_region_name = cb_state.GetDebugLabelRegion(label_command_i, initial_label_stack);
        Location loc_with_debug_region(loc, debug_region_name);

        switch (error_record[kHeaderErrorSubCodeOffset]) {
            case kErrorSubCodePreDraw_DrawBufferSize: {
                const uint32_t count = error_record[kPreActionParamOffset_0];

                const VkDeviceSize draw_size =
                    (draw_cmds_byte_stride * (count - 1) + draw_buffer_offset + draw_indirect_struct_byte_size);

                // Discussed that if drawCount is largeer than the buffer, it is still capped by the maxDrawCount on the CPU (which
                // we would have checked is in the buffer range). We decided that we still want to give a warning, but the nothing
                // is invalid here. https://gitlab.khronos.org/vulkan/vulkan/-/issues/3991
                skip |= gpuav.LogWarning("WARNING-GPU-AV-drawCount", objlist, loc_with_debug_region,
                                         "Indirect draw count of %" PRIu32 " would exceed size (%" PRIu64
                                         ") of buffer (%s). "
                                         "stride = %" PRIu32 " offset = %" PRIu64
                                         " (stride * (drawCount - 1) + offset + sizeof(%s)) = %" PRIu64 ".",
                                         count, draw_buffer_size, gpuav.FormatHandle(draw_buffer).c_str(), draw_cmds_byte_stride,
                                         draw_buffer_offset, vvl::String(draw_indirect_struct_name), draw_size);
                break;
            }
            case kErrorSubCodePreDraw_DrawCountLimit: {
                const uint32_t count = error_record[kPreActionParamOffset_0];
                skip |= gpuav.LogError(vuid_max_draw_count, objlist, loc_with_debug_region,
                                       "Indirect draw count of %" PRIu32 " would exceed maxDrawIndirectCount limit of %" PRIu32 ".",
                                       count, gpuav.phys_dev_props.limits.maxDrawIndirectCount);
                break;
            }
            default:
                assert(false);
                return skip;
        }

        return skip;
    };

    cb_state.per_command_error_loggers.emplace_back(std::move(error_logger));
}

struct MeshValidationShader {
    static size_t GetSpirvSize() { return cmd_validation_draw_mesh_indirect_comp_size * sizeof(uint32_t); }
    static const uint32_t *GetSpirv() { return cmd_validation_draw_mesh_indirect_comp; }

    static const uint32_t desc_set_id = gpuav::glsl::kDiagPerCmdDescriptorSet;

    glsl::DrawMeshPushData push_constants{};
    BoundStorageBuffer draw_buffer_binding = {gpuav::glsl::kPreDrawBinding_IndirectBuffer};
    BoundStorageBuffer count_buffer_binding = {gpuav::glsl::kPreDrawBinding_CountBuffer};

    static std::vector<VkDescriptorSetLayoutBinding> GetDescriptorSetLayoutBindings() {
        std::vector<VkDescriptorSetLayoutBinding> bindings = {
            {gpuav::glsl::kPreDrawBinding_IndirectBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT,
             nullptr},  // indirect buffer
            {gpuav::glsl::kPreDrawBinding_CountBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT,
             nullptr},  // count buffer
        };

        return bindings;
    }

    std::vector<VkWriteDescriptorSet> GetDescriptorWrites(VkDescriptorSet desc_set) const {
        std::vector<VkWriteDescriptorSet> desc_writes(2);

        desc_writes[0] = vku::InitStructHelper();
        desc_writes[0].dstSet = desc_set;
        desc_writes[0].dstBinding = draw_buffer_binding.binding;
        desc_writes[0].dstArrayElement = 0;
        desc_writes[0].descriptorCount = 1;
        desc_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
        desc_writes[0].pBufferInfo = &draw_buffer_binding.info;

        desc_writes[1] = vku::InitStructHelper();
        desc_writes[1].dstSet = desc_set;
        desc_writes[1].dstBinding = count_buffer_binding.binding;
        desc_writes[1].dstArrayElement = 0;
        desc_writes[1].descriptorCount = 1;
        desc_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
        desc_writes[1].pBufferInfo = &count_buffer_binding.info;

        return desc_writes;
    }
};

void DrawMeshIndirect(Validator &gpuav, CommandBuffer &cb_state, const Location &loc, VkBuffer draw_buffer,
                      VkDeviceSize draw_buffer_offset, uint32_t draw_cmds_byte_stride, VkBuffer count_buffer,
                      VkDeviceSize count_buffer_offset, uint32_t draw_count) {
    if (!gpuav.gpuav_settings.validate_indirect_draws_buffers) {
        return;
    }

    auto draw_buffer_state = gpuav.Get<vvl::Buffer>(draw_buffer);
    if (!draw_buffer_state) {
        gpuav.InternalError(LogObjectList(cb_state.VkHandle(), draw_buffer), loc, "buffer must be a valid VkBuffer handle");
        return;
    }

    const LvlBindPoint lv_bind_point = ConvertToLvlBindPoint(VK_PIPELINE_BIND_POINT_GRAPHICS);
    const LastBound &last_bound = cb_state.lastBound[lv_bind_point];
    const vvl::Pipeline *pipeline_state = last_bound.pipeline_state;
    const VkShaderStageFlags stages = pipeline_state->create_info_shaders;
    const bool is_task_shader = (stages & VK_SHADER_STAGE_TASK_BIT_EXT) == VK_SHADER_STAGE_TASK_BIT_EXT;

    CommandBuffer::ValidationCommandFunc validation_cmd =
        [draw_buffer, draw_buffer_full_size = draw_buffer_state->create_info.size, draw_buffer_offset, draw_cmds_byte_stride,
         count_buffer, count_buffer_offset, draw_count, is_task_shader, draw_i = cb_state.draw_index,
         error_logger_i = uint32_t(cb_state.per_command_error_loggers.size()), loc](Validator &gpuav, CommandBuffer &cb_state) {
            SharedDrawValidationResources &shared_draw_validation_resources =
                gpuav.shared_resources_manager.Get<SharedDrawValidationResources>(gpuav, loc);
            if (!shared_draw_validation_resources.valid) return;
            ComputeValidationPipeline<MeshValidationShader> &validation_pipeline =
                gpuav.shared_resources_manager.Get<ComputeValidationPipeline<MeshValidationShader>>(
                    gpuav, loc, cb_state.GetErrorLoggingDescSetLayout());
            if (!validation_pipeline.valid) return;

            // Setup shader resources
            // ---
            {
                MeshValidationShader shader_resources;
                shader_resources.push_constants.draw_cmds_stride_dwords = draw_cmds_byte_stride / sizeof(uint32_t);
                shader_resources.push_constants.cpu_draw_count = draw_count;
                if (is_task_shader) {
                    shader_resources.push_constants.max_workgroup_count_x =
                        gpuav.phys_dev_ext_props.mesh_shader_props_ext.maxTaskWorkGroupCount[0];
                    shader_resources.push_constants.max_workgroup_count_y =
                        gpuav.phys_dev_ext_props.mesh_shader_props_ext.maxTaskWorkGroupCount[1];
                    shader_resources.push_constants.max_workgroup_count_z =
                        gpuav.phys_dev_ext_props.mesh_shader_props_ext.maxTaskWorkGroupCount[2];
                    shader_resources.push_constants.max_workgroup_total_count =
                        gpuav.phys_dev_ext_props.mesh_shader_props_ext.maxTaskWorkGroupTotalCount;
                } else {
                    shader_resources.push_constants.max_workgroup_count_x =
                        gpuav.phys_dev_ext_props.mesh_shader_props_ext.maxMeshWorkGroupCount[0];
                    shader_resources.push_constants.max_workgroup_count_y =
                        gpuav.phys_dev_ext_props.mesh_shader_props_ext.maxMeshWorkGroupCount[1];
                    shader_resources.push_constants.max_workgroup_count_z =
                        gpuav.phys_dev_ext_props.mesh_shader_props_ext.maxMeshWorkGroupCount[2];
                    shader_resources.push_constants.max_workgroup_total_count =
                        gpuav.phys_dev_ext_props.mesh_shader_props_ext.maxMeshWorkGroupTotalCount;
                }

                shader_resources.draw_buffer_binding.info = {draw_buffer, 0, VK_WHOLE_SIZE};
                shader_resources.push_constants.draw_buffer_dwords_offset = (uint32_t)draw_buffer_offset / sizeof(uint32_t);
                if (count_buffer != VK_NULL_HANDLE) {
                    shader_resources.push_constants.flags |= glsl::kDrawMeshFlags_DrawCountFromBuffer;
                    shader_resources.count_buffer_binding.info = {count_buffer, 0, sizeof(uint32_t)};
                    shader_resources.push_constants.count_buffer_dwords_offset = (uint32_t)count_buffer_offset / sizeof(uint32_t);
                } else {
                    shader_resources.count_buffer_binding.info = {shared_draw_validation_resources.dummy_buffer.VkHandle(), 0,
                                                                  VK_WHOLE_SIZE};
                }

                validation_pipeline.BindShaderResources(gpuav, cb_state, draw_i, error_logger_i, shader_resources);
            }

            // Setup validation pipeline
            // ---
            {
                DispatchCmdBindPipeline(cb_state.VkHandle(), VK_PIPELINE_BIND_POINT_COMPUTE, validation_pipeline.pipeline);

                uint32_t max_held_draw_cmds = 0;
                if (draw_buffer_full_size > draw_buffer_offset) {
                    // If drawCount is less than or equal to one, stride is ignored
                    if (draw_count > 1) {
                        max_held_draw_cmds =
                            static_cast<uint32_t>((draw_buffer_full_size - draw_buffer_offset) / draw_cmds_byte_stride);
                    } else {
                        max_held_draw_cmds = 1;
                    }
                }
                const uint32_t work_group_count = std::min(draw_count, max_held_draw_cmds);
                VVL_TracyPlot("gpuav::valcmd::DrawMeshIndirect Dispatch size", int64_t(work_group_count));
                DispatchCmdDispatch(cb_state.VkHandle(), work_group_count, 1, 1);

                // synchronize draw buffer validation (read) against subsequent writes
                std::array<VkBufferMemoryBarrier, 2> buffer_memory_barriers = {};
                uint32_t buffer_memory_barriers_count = 1;
                buffer_memory_barriers[0] = vku::InitStructHelper();
                buffer_memory_barriers[0].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
                buffer_memory_barriers[0].dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
                buffer_memory_barriers[0].buffer = draw_buffer;
                buffer_memory_barriers[0].offset = draw_buffer_offset;
                buffer_memory_barriers[0].size = work_group_count * sizeof(uint32_t);

                if (count_buffer) {
                    buffer_memory_barriers[1] = vku::InitStructHelper();
                    buffer_memory_barriers[1].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
                    buffer_memory_barriers[1].dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
                    buffer_memory_barriers[1].buffer = count_buffer;
                    buffer_memory_barriers[1].offset = count_buffer_offset;
                    buffer_memory_barriers[1].size = sizeof(uint32_t);
                    ++buffer_memory_barriers_count;
                }

                DispatchCmdPipelineBarrier(cb_state.VkHandle(), VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
                                           VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, buffer_memory_barriers_count,
                                           buffer_memory_barriers.data(), 0, nullptr);
            }
        };
    cb_state.per_render_pass_validation_commands.emplace_back(std::move(validation_cmd));

    // Register error logger
    // ---
    const uint32_t label_command_i =
        !cb_state.GetLabelCommands().empty() ? uint32_t(cb_state.GetLabelCommands().size() - 1) : vvl::kU32Max;
    CommandBuffer::ErrorLoggerFunc error_logger = [loc, is_task_shader, label_command_i](
                                                      Validator &gpuav, const CommandBuffer &cb_state, const uint32_t *error_record,
                                                      const LogObjectList &objlist,
                                                      const std::vector<std::string> &initial_label_stack) {
        bool skip = false;

        using namespace glsl;

        const char *vuid_task_group_count_exceeds_max_x = "VUID-VkDrawMeshTasksIndirectCommandEXT-TaskEXT-07322";
        const char *vuid_task_group_count_exceeds_max_y = "VUID-VkDrawMeshTasksIndirectCommandEXT-TaskEXT-07323";
        const char *vuid_task_group_count_exceeds_max_z = "VUID-VkDrawMeshTasksIndirectCommandEXT-TaskEXT-07324";
        const char *vuid_task_group_count_exceeds_max_total = "VUID-VkDrawMeshTasksIndirectCommandEXT-TaskEXT-07325";
        const char *vuid_mesh_group_count_exceeds_max_x = "VUID-VkDrawMeshTasksIndirectCommandEXT-TaskEXT-07326";
        const char *vuid_mesh_group_count_exceeds_max_y = "VUID-VkDrawMeshTasksIndirectCommandEXT-TaskEXT-07327";
        const char *vuid_mesh_group_count_exceeds_max_z = "VUID-VkDrawMeshTasksIndirectCommandEXT-TaskEXT-07328";
        const char *vuid_mesh_group_count_exceeds_max_total = "VUID-VkDrawMeshTasksIndirectCommandEXT-TaskEXT-07329";

        const uint32_t draw_i = error_record[kPreActionParamOffset_1];
        const char *group_count_name = is_task_shader ? "maxTaskWorkGroupCount" : "maxMeshWorkGroupCount";
        const char *group_count_total_name = is_task_shader ? "maxTaskWorkGroupTotalCount" : "maxMeshWorkGroupTotalCount";

        std::string debug_region_name = cb_state.GetDebugLabelRegion(label_command_i, initial_label_stack);
        Location loc_with_debug_region(loc, debug_region_name);

        switch (error_record[kHeaderErrorSubCodeOffset]) {
            case kErrorSubCodePreDrawGroupCountX: {
                const char *vuid_group_count_exceeds_max =
                    is_task_shader ? vuid_task_group_count_exceeds_max_x : vuid_mesh_group_count_exceeds_max_x;
                const uint32_t group_count_x = error_record[kPreActionParamOffset_0];
                const uint32_t limit = is_task_shader ? gpuav.phys_dev_ext_props.mesh_shader_props_ext.maxTaskWorkGroupCount[0]
                                                      : gpuav.phys_dev_ext_props.mesh_shader_props_ext.maxMeshWorkGroupCount[0];
                skip |= gpuav.LogError(vuid_group_count_exceeds_max, objlist, loc_with_debug_region,
                                       "In draw %" PRIu32 ", VkDrawMeshTasksIndirectCommandEXT::groupCountX is %" PRIu32
                                       " which is greater than VkPhysicalDeviceMeshShaderPropertiesEXT::%s[0]"
                                       " (%" PRIu32 ").",
                                       draw_i, group_count_x, group_count_name, limit);
                break;
            }

            case kErrorSubCodePreDrawGroupCountY: {
                const char *vuid_group_count_exceeds_max =
                    is_task_shader ? vuid_task_group_count_exceeds_max_y : vuid_mesh_group_count_exceeds_max_y;
                const uint32_t group_count_y = error_record[kPreActionParamOffset_0];
                const uint32_t limit = is_task_shader ? gpuav.phys_dev_ext_props.mesh_shader_props_ext.maxTaskWorkGroupCount[1]
                                                      : gpuav.phys_dev_ext_props.mesh_shader_props_ext.maxMeshWorkGroupCount[1];
                skip |= gpuav.LogError(vuid_group_count_exceeds_max, objlist, loc_with_debug_region,
                                       "In draw %" PRIu32 ", VkDrawMeshTasksIndirectCommandEXT::groupCountY is %" PRIu32
                                       " which is greater than VkPhysicalDeviceMeshShaderPropertiesEXT::%s[1]"
                                       " (%" PRIu32 ").",
                                       draw_i, group_count_y, group_count_name, limit);
                break;
            }

            case kErrorSubCodePreDrawGroupCountZ: {
                const char *vuid_group_count_exceeds_max =
                    is_task_shader ? vuid_task_group_count_exceeds_max_z : vuid_mesh_group_count_exceeds_max_z;
                const uint32_t group_count_z = error_record[kPreActionParamOffset_0];
                const uint32_t limit = is_task_shader ? gpuav.phys_dev_ext_props.mesh_shader_props_ext.maxTaskWorkGroupCount[2]
                                                      : gpuav.phys_dev_ext_props.mesh_shader_props_ext.maxMeshWorkGroupCount[2];
                skip |= gpuav.LogError(vuid_group_count_exceeds_max, objlist, loc_with_debug_region,
                                       "In draw %" PRIu32 ", VkDrawMeshTasksIndirectCommandEXT::groupCountZ is %" PRIu32
                                       " which is greater than VkPhysicalDeviceMeshShaderPropertiesEXT::%s[2]"
                                       " (%" PRIu32 ").",
                                       draw_i, group_count_z, group_count_name, limit);
                break;
            }

            case kErrorSubCodePreDrawGroupCountTotal: {
                const char *vuid_group_count_exceeds_max =
                    is_task_shader ? vuid_task_group_count_exceeds_max_total : vuid_mesh_group_count_exceeds_max_total;
                const uint32_t group_count_total = error_record[kPreActionParamOffset_0];
                const uint32_t limit = is_task_shader ? gpuav.phys_dev_ext_props.mesh_shader_props_ext.maxTaskWorkGroupTotalCount
                                                      : gpuav.phys_dev_ext_props.mesh_shader_props_ext.maxMeshWorkGroupTotalCount;
                skip |= gpuav.LogError(vuid_group_count_exceeds_max, objlist, loc_with_debug_region,
                                       "In draw %" PRIu32 ", size of VkDrawMeshTasksIndirectCommandEXT is %" PRIu32
                                       " which is greater than VkPhysicalDeviceMeshShaderPropertiesEXT::%s"
                                       " (%" PRIu32 ").",
                                       draw_i, group_count_total, group_count_total_name, limit);
                break;
            }

            default:
                assert(false);
                return skip;
        }

        return skip;
    };

    cb_state.per_command_error_loggers.emplace_back(std::move(error_logger));
}

struct SmallestVertexBufferBinding {
    VkDeviceSize smallest_vertex_attributes_count = std::numeric_limits<VkDeviceSize>::max();
    uint32_t binding = std::numeric_limits<uint32_t>::max();
    vvl::VertexBufferBinding binding_info{};
    struct Attribute {
        uint32_t location{};
        uint32_t binding{};
        VkFormat format{};
        uint32_t offset{};
    } attribute;
};
// Computes the smallest vertex attributes count among the set of bound vertex buffers.
// Used to detect out of bounds indices in index buffers.
// If no vertex buffer is bound, smallest_vertex_attributes_count is std::numeric_limits<uint32_t>::max()
// indicating that no index can be out of bound
static std::optional<SmallestVertexBufferBinding> SmallestVertexAttributesCount(const vvl::CommandBuffer &cb_state) {
    const LvlBindPoint lv_bind_point = ConvertToLvlBindPoint(VK_PIPELINE_BIND_POINT_GRAPHICS);
    const LastBound &last_bound = cb_state.lastBound[lv_bind_point];
    const vvl::Pipeline *pipeline_state = last_bound.pipeline_state;
    const bool use_shader_objects = pipeline_state == nullptr;

    const bool dynamic_vertex_input = use_shader_objects || pipeline_state->IsDynamic(CB_DYNAMIC_STATE_VERTEX_INPUT_EXT);

    const auto &vertex_binding_descriptions =
        dynamic_vertex_input ? cb_state.dynamic_state_value.vertex_bindings : pipeline_state->vertex_input_state->bindings;

    std::optional<SmallestVertexBufferBinding> smallest_vertex_buffer_binding;

    for (const auto &[binding, vertex_binding_desc] : vertex_binding_descriptions) {
        auto find_vbb = cb_state.current_vertex_buffer_binding_info.find(binding);
        if (find_vbb == cb_state.current_vertex_buffer_binding_info.cend()) {
            // This is a validation error
            continue;
        }

        const vvl::VertexBufferBinding &vbb = find_vbb->second;

        // #ARNO_TODO: Should I only loop over vertex attributes actually used by bound pipelines,
        // according to its vertex shader?
        for (const auto &[Location, attrib] : vertex_binding_desc.locations) {
            const VkDeviceSize attribute_size = vkuFormatElementSize(attrib.desc.format);

            const VkDeviceSize stride =
                vbb.stride != 0 ? vbb.stride : attribute_size;  // Tracked stride should already handle all possible value origin

            VkDeviceSize vertex_buffer_remaining_size =
                vbb.effective_size > attrib.desc.offset ? vbb.effective_size - attrib.desc.offset : 0;

            VkDeviceSize vertex_attributes_count = vertex_buffer_remaining_size / stride;
            if (vertex_buffer_remaining_size > vertex_attributes_count * stride) {
                vertex_buffer_remaining_size -= vertex_attributes_count * stride;
            } else {
                vertex_buffer_remaining_size = 0;
            }

            // maybe room for one more attribute but not full stride - not having stride space does not matter for last element
            if (vertex_buffer_remaining_size >= attribute_size) {
                vertex_attributes_count += 1;
            }

            if (!smallest_vertex_buffer_binding.has_value()) {
                smallest_vertex_buffer_binding = SmallestVertexBufferBinding{};
            }
            smallest_vertex_buffer_binding->smallest_vertex_attributes_count =
                std::min(smallest_vertex_buffer_binding->smallest_vertex_attributes_count, vertex_attributes_count);
            if (smallest_vertex_buffer_binding->smallest_vertex_attributes_count == vertex_attributes_count) {
                smallest_vertex_buffer_binding->binding = binding;
                smallest_vertex_buffer_binding->binding_info = vbb;
                smallest_vertex_buffer_binding->attribute.location = attrib.desc.location;
                smallest_vertex_buffer_binding->attribute.binding = attrib.desc.binding;
                smallest_vertex_buffer_binding->attribute.format = attrib.desc.format;
                smallest_vertex_buffer_binding->attribute.offset = attrib.desc.offset;
            }
        }
    }
    return smallest_vertex_buffer_binding;
}

struct IndexBufferValidationShader {
    static size_t GetSpirvSize() { return cmd_validation_draw_indexed_comp_size * sizeof(uint32_t); }
    static const uint32_t *GetSpirv() { return cmd_validation_draw_indexed_comp; }

    static const uint32_t desc_set_id = gpuav::glsl::kDiagPerCmdDescriptorSet;

    glsl::IndexedDrawPushData push_constants{};
    BoundStorageBuffer index_buffer_binding = {gpuav::glsl::kPreDrawBinding_IndexBuffer};

    static std::vector<VkDescriptorSetLayoutBinding> GetDescriptorSetLayoutBindings() {
        std::vector<VkDescriptorSetLayoutBinding> bindings = {
            {gpuav::glsl::kPreDrawBinding_IndexBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}};

        return bindings;
    }

    std::vector<VkWriteDescriptorSet> GetDescriptorWrites(VkDescriptorSet desc_set) const {
        std::vector<VkWriteDescriptorSet> desc_writes(1);

        desc_writes[0] = vku::InitStructHelper();
        desc_writes[0].dstSet = desc_set;
        desc_writes[0].dstBinding = index_buffer_binding.binding;
        desc_writes[0].dstArrayElement = 0;
        desc_writes[0].descriptorCount = 1;
        desc_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
        desc_writes[0].pBufferInfo = &index_buffer_binding.info;

        return desc_writes;
    }
};

void DrawIndexed(Validator &gpuav, CommandBuffer &cb_state, const Location &loc, uint32_t index_count, uint32_t first_index,
                 uint32_t vertex_offset, const char *vuid_oob_vertex) {
    if (!gpuav.gpuav_settings.validate_index_buffers) {
        return;
    }

    if (gpuav.enabled_features.robustBufferAccess) {
        return;
    }

    const LvlBindPoint lv_bind_point = ConvertToLvlBindPoint(VK_PIPELINE_BIND_POINT_GRAPHICS);
    const LastBound &last_bound = cb_state.lastBound[lv_bind_point];
    const vvl::Pipeline *pipeline_state = last_bound.pipeline_state;
    if (pipeline_state) {
        const auto robustness_ci =
            vku::FindStructInPNextChain<VkPipelineRobustnessCreateInfo>(pipeline_state->GraphicsCreateInfo().pNext);
        if (robustness_ci && robustness_ci->vertexInputs) {
            return;
        }
    }

    if (!cb_state.IsPrimary()) {
        // TODO Unhandled for now. Potential issues with accessing the right vertex buffers
        // in secondary command buffers
        return;
    }

    if (!cb_state.index_buffer_binding.buffer) {
        return;
    }

    const std::optional<SmallestVertexBufferBinding> smallest_vertex_buffer_binding = SmallestVertexAttributesCount(cb_state);
    if (!smallest_vertex_buffer_binding.has_value()) {
        // cannot overrun index buffer, skip validation
        return;
    }

    CommandBuffer::ValidationCommandFunc validation_cmd = [index_buffer_binding = cb_state.index_buffer_binding, index_count,
                                                           first_index, vertex_offset,
                                                           smallest_vertex_buffer_binding = *smallest_vertex_buffer_binding,
                                                           draw_i = cb_state.draw_index,
                                                           error_logger_i = uint32_t(cb_state.per_command_error_loggers.size()),
                                                           loc](Validator &gpuav, CommandBuffer &cb_state) {
        SharedDrawValidationResources &shared_draw_validation_resources =
            gpuav.shared_resources_manager.Get<SharedDrawValidationResources>(gpuav, loc);
        if (!shared_draw_validation_resources.valid) return;
        ComputeValidationPipeline<IndexBufferValidationShader> &validation_pipeline =
            gpuav.shared_resources_manager.Get<ComputeValidationPipeline<IndexBufferValidationShader>>(
                gpuav, loc, cb_state.GetErrorLoggingDescSetLayout());
        if (!validation_pipeline.valid) return;

        const uint32_t index_bits_size = GetIndexBitsSize(index_buffer_binding.index_type);
        const uint32_t max_indices_in_buffer = static_cast<uint32_t>(index_buffer_binding.size / (index_bits_size / 8u));
        const uint32_t indices_to_check = std::min(index_count, max_indices_in_buffer);

        {
            IndexBufferValidationShader shader_resources;
            shader_resources.push_constants.smallest_vertex_attributes_count =
                static_cast<uint32_t>(smallest_vertex_buffer_binding.smallest_vertex_attributes_count);
            shader_resources.push_constants.index_width = index_bits_size;
            shader_resources.push_constants.vertex_offset = vertex_offset;
            shader_resources.push_constants.first_index = first_index;

            shader_resources.index_buffer_binding.info = {index_buffer_binding.buffer, 0,
                                                          index_buffer_binding.offset + index_buffer_binding.size};
            shader_resources.push_constants.index_buffer_dwords_offset = (uint32_t)index_buffer_binding.offset / sizeof(uint32_t);
            shader_resources.push_constants.indices_to_check = indices_to_check;

            validation_pipeline.BindShaderResources(gpuav, cb_state, draw_i, error_logger_i, shader_resources);
        }

        {
            DispatchCmdBindPipeline(cb_state.VkHandle(), VK_PIPELINE_BIND_POINT_COMPUTE, validation_pipeline.pipeline);

            // Do not overrun index buffer
            constexpr uint32_t work_group_size = 64;
            const uint32_t work_group_count =
                indices_to_check / work_group_size + uint32_t(indices_to_check % work_group_size != 0);
            VVL_TracyPlot("gpuav::valcmd::DrawIndexed Dispatch size", int64_t(work_group_count));
            DispatchCmdDispatch(cb_state.VkHandle(), work_group_count, 1, 1);
            // synchronize draw buffer validation (read) against subsequent writes
            VkBufferMemoryBarrier index_buffer_memory_barrier = vku::InitStructHelper();
            index_buffer_memory_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
            index_buffer_memory_barrier.dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
            index_buffer_memory_barrier.buffer = index_buffer_binding.buffer;
            index_buffer_memory_barrier.offset = index_buffer_binding.offset;
            index_buffer_memory_barrier.size = index_buffer_binding.size;

            DispatchCmdPipelineBarrier(cb_state.VkHandle(), VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
                                       VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 1, &index_buffer_memory_barrier, 0,
                                       nullptr);
        }
    };
    cb_state.per_render_pass_validation_commands.emplace_back(std::move(validation_cmd));

    const uint32_t label_command_i =
        !cb_state.GetLabelCommands().empty() ? uint32_t(cb_state.GetLabelCommands().size() - 1) : vvl::kU32Max;
    CommandBuffer::ErrorLoggerFunc error_logger =
        [loc, vuid_oob_vertex, smallest_vertex_buffer_binding = *smallest_vertex_buffer_binding,
         index_buffer_binding = cb_state.index_buffer_binding,
         label_command_i](Validator &gpuav, const CommandBuffer &cb_state, const uint32_t *error_record,
                          const LogObjectList &objlist, const std::vector<std::string> &initial_label_stack) {
            bool skip = false;

            using namespace glsl;

            switch (error_record[kHeaderErrorSubCodeOffset]) {
                case kErrorSubCode_OobVertexBuffer: {
                    const uint32_t index_buffer_offset = error_record[kPreActionParamOffset_0];
                    const int32_t vertex_offset = static_cast<int32_t>(error_record[kPreActionParamOffset_1]);
                    const uint32_t vertex_index = error_record[kPreActionParamOffset_2];
                    const uint32_t index_buffer_value = static_cast<uint32_t>(int32_t(vertex_index) - vertex_offset);
                    const uint32_t index_bits_size = GetIndexBitsSize(index_buffer_binding.index_type);
                    const uint32_t max_indices_in_buffer =
                        static_cast<uint32_t>(index_buffer_binding.size / (index_bits_size / 8u));

                    std::string debug_region_name = cb_state.GetDebugLabelRegion(label_command_i, initial_label_stack);
                    Location loc_with_debug_region(loc, debug_region_name);
                    skip |= gpuav.LogError(
                        vuid_oob_vertex, objlist, loc_with_debug_region,
                        "Vertex index %" PRIu32
                        " is not within the smallest bound vertex buffer.\n"
                        "index_buffer[ %" PRIu32 " ] (%" PRIu32 ") + vertexOffset (%" PRIi32 ") = Vertex index %" PRIu32
                        "\n"

                        "Smallest vertex buffer binding info, causing OOB access:\n"
                        "- Buffer: %s\n"
                        "- Binding: %" PRIu32
                        "\n"
                        "- Binding size (effective): %" PRIu64
                        " bytes\n"
                        "- Binding offset: %" PRIu64
                        " bytes\n"
                        "- Binding stride: %" PRIu64
                        " bytes\n"
                        "- Vertices count: %" PRIu64
                        "\n"

                        "At least the following vertex attribute caused OOB access:\n"
                        "- location: %" PRIu32
                        "\n"
                        "- binding: %" PRIu32
                        "\n"
                        "- format: %s\n"
                        "- offset: %" PRIu32
                        " bytes\n"

                        "Index buffer binding info:\n"
                        "- Buffer: %s\n"
                        "- Index type: %s\n"
                        "- Binding offset: %" PRIu64
                        " bytes\n"
                        "- Binding size: %" PRIu64 " bytes (or %" PRIu32
                        " %s)\n"

                        "Note: Vertex buffer binding size is the effective, valid one, based on how the VkBuffer was created and "
                        "vertex buffer binding parameters. So it can be clamped up to 0 if binding was invalid.\n",
                        // OOB vertex index info
                        vertex_index, index_buffer_offset, index_buffer_value, vertex_offset, vertex_index,

                        // Vertex buffer binding info
                        gpuav.FormatHandle(smallest_vertex_buffer_binding.binding_info.buffer).c_str(),
                        smallest_vertex_buffer_binding.binding, smallest_vertex_buffer_binding.binding_info.effective_size,
                        smallest_vertex_buffer_binding.binding_info.offset, smallest_vertex_buffer_binding.binding_info.stride,
                        smallest_vertex_buffer_binding.smallest_vertex_attributes_count,

                        // Vertex Attribute info
                        smallest_vertex_buffer_binding.attribute.location, smallest_vertex_buffer_binding.attribute.binding,
                        string_VkFormat(smallest_vertex_buffer_binding.attribute.format),
                        smallest_vertex_buffer_binding.attribute.offset,

                        // Index buffer binding info
                        gpuav.FormatHandle(index_buffer_binding.buffer).c_str(),
                        string_VkIndexType(index_buffer_binding.index_type), index_buffer_binding.offset, index_buffer_binding.size,
                        max_indices_in_buffer, string_VkIndexType(index_buffer_binding.index_type));
                    break;
                }

                default:
                    assert(false);
                    return skip;
            }

            return skip;
        };

    cb_state.per_command_error_loggers.emplace_back(std::move(error_logger));
}

struct DrawIndexedIndirectIndexBufferShader {
    static size_t GetSpirvSize() { return cmd_validation_draw_indexed_indirect_index_buffer_comp_size * sizeof(uint32_t); }
    static const uint32_t *GetSpirv() { return cmd_validation_draw_indexed_indirect_index_buffer_comp; }

    static const uint32_t desc_set_id = gpuav::glsl::kDiagPerCmdDescriptorSet;

    glsl::DrawIndexedIndirectIndexBufferPushData push_constants{};
    BoundStorageBuffer draw_buffer_binding = {gpuav::glsl::kPreDrawBinding_IndirectBuffer};
    BoundStorageBuffer count_buffer_binding = {gpuav::glsl::kPreDrawBinding_CountBuffer};

    static std::vector<VkDescriptorSetLayoutBinding> GetDescriptorSetLayoutBindings() {
        std::vector<VkDescriptorSetLayoutBinding> bindings = {
            {gpuav::glsl::kPreDrawBinding_IndirectBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT,
             nullptr},
            {gpuav::glsl::kPreDrawBinding_CountBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
            {gpuav::glsl::kPreDrawBinding_IndexBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}};

        return bindings;
    }

    std::vector<VkWriteDescriptorSet> GetDescriptorWrites(VkDescriptorSet desc_set) const {
        std::vector<VkWriteDescriptorSet> desc_writes(2);

        desc_writes[0] = vku::InitStructHelper();
        desc_writes[0].dstSet = desc_set;
        desc_writes[0].dstBinding = draw_buffer_binding.binding;
        desc_writes[0].dstArrayElement = 0;
        desc_writes[0].descriptorCount = 1;
        desc_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
        desc_writes[0].pBufferInfo = &draw_buffer_binding.info;

        desc_writes[1] = vku::InitStructHelper();
        desc_writes[1].dstSet = desc_set;
        desc_writes[1].dstBinding = count_buffer_binding.binding;
        desc_writes[1].dstArrayElement = 0;
        desc_writes[1].descriptorCount = 1;
        desc_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
        desc_writes[1].pBufferInfo = &count_buffer_binding.info;

        return desc_writes;
    }
};

void DrawIndexedIndirectIndexBuffer(Validator &gpuav, CommandBuffer &cb_state, const Location &loc, VkBuffer draw_buffer,
                                    VkDeviceSize draw_buffer_offset, uint32_t draw_cmds_byte_stride, uint32_t draw_count,
                                    VkBuffer count_buffer, VkDeviceSize count_buffer_offset, const char *vuid_oob_index) {
    if (!gpuav.gpuav_settings.validate_index_buffers) {
        return;
    }

    if (gpuav.enabled_features.robustBufferAccess2) {
        return;
    }

    if (gpuav.enabled_features.pipelineRobustness) {
        const LvlBindPoint lv_bind_point = ConvertToLvlBindPoint(VK_PIPELINE_BIND_POINT_GRAPHICS);
        const LastBound &last_bound = cb_state.lastBound[lv_bind_point];
        const vvl::Pipeline *pipeline_state = last_bound.pipeline_state;
        if (pipeline_state) {
            const auto robustness_ci =
                vku::FindStructInPNextChain<VkPipelineRobustnessCreateInfo>(pipeline_state->GraphicsCreateInfo().pNext);
            if (robustness_ci && robustness_ci->vertexInputs) {
                return;
            }
        }
    }

    if (!cb_state.IsPrimary()) {
        // TODO Unhandled for now. Potential issues with accessing the right vertex buffers
        // in secondary command buffers
        return;
    }

    if (!cb_state.index_buffer_binding.buffer) {
        return;
    }

    CommandBuffer::ValidationCommandFunc validation_cmd = [index_buffer_binding = cb_state.index_buffer_binding, draw_buffer,
                                                           draw_buffer_offset, draw_cmds_byte_stride, draw_count, count_buffer,
                                                           count_buffer_offset, draw_i = cb_state.draw_index,
                                                           error_logger_i = uint32_t(cb_state.per_command_error_loggers.size()),
                                                           loc](Validator &gpuav, CommandBuffer &cb_state) {
        SharedDrawValidationResources &shared_draw_validation_resources =
            gpuav.shared_resources_manager.Get<SharedDrawValidationResources>(gpuav, loc);
        if (!shared_draw_validation_resources.valid) return;
        ComputeValidationPipeline<DrawIndexedIndirectIndexBufferShader> &validation_pipeline =
            gpuav.shared_resources_manager.Get<ComputeValidationPipeline<DrawIndexedIndirectIndexBufferShader>>(
                gpuav, loc, cb_state.GetErrorLoggingDescSetLayout());
        if (!validation_pipeline.valid) return;

        const uint32_t index_bits_size = GetIndexBitsSize(index_buffer_binding.index_type);
        const uint32_t max_indices_in_buffer = static_cast<uint32_t>(index_buffer_binding.size / (index_bits_size / 8u));
        {
            DrawIndexedIndirectIndexBufferShader shader_resources;
            if (count_buffer != VK_NULL_HANDLE) {
                shader_resources.push_constants.flags |= glsl::kIndexedIndirectDrawFlags_DrawCountFromBuffer;
                shader_resources.count_buffer_binding.info = {count_buffer, 0, sizeof(uint32_t)};
                shader_resources.push_constants.count_buffer_dwords_offset = (uint32_t)count_buffer_offset / sizeof(uint32_t);

            } else {
                shader_resources.count_buffer_binding.info = {shared_draw_validation_resources.dummy_buffer.VkHandle(), 0,
                                                              VK_WHOLE_SIZE};
            }

            shader_resources.push_constants.draw_cmds_stride_dwords = draw_cmds_byte_stride / sizeof(uint32_t);
            shader_resources.push_constants.bound_index_buffer_indices_count = max_indices_in_buffer;
            shader_resources.push_constants.cpu_draw_count = draw_count;

            shader_resources.draw_buffer_binding.info = {draw_buffer, 0, VK_WHOLE_SIZE};
            shader_resources.push_constants.draw_indexed_indirect_cmds_buffer_dwords_offset =
                (uint32_t)draw_buffer_offset / sizeof(uint32_t);

            validation_pipeline.BindShaderResources(gpuav, cb_state, draw_i, error_logger_i, shader_resources);
        }

        {
            DispatchCmdBindPipeline(cb_state.VkHandle(), VK_PIPELINE_BIND_POINT_COMPUTE, validation_pipeline.pipeline);

            // One draw will check all VkDrawIndexedIndirectCommand
            DispatchCmdDispatch(cb_state.VkHandle(), 1, 1, 1);
            // synchronize draw buffer validation (read) against subsequent writes
            std::array<VkBufferMemoryBarrier, 2> buffer_memory_barriers = {};
            uint32_t buffer_memory_barriers_count = 1;
            buffer_memory_barriers[0] = vku::InitStructHelper();
            buffer_memory_barriers[0].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
            buffer_memory_barriers[0].dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
            buffer_memory_barriers[0].buffer = draw_buffer;
            buffer_memory_barriers[0].offset = draw_buffer_offset;
            buffer_memory_barriers[0].size = VK_WHOLE_SIZE;

            if (count_buffer) {
                buffer_memory_barriers[1] = vku::InitStructHelper();
                buffer_memory_barriers[1].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
                buffer_memory_barriers[1].dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
                buffer_memory_barriers[1].buffer = count_buffer;
                buffer_memory_barriers[1].offset = count_buffer_offset;
                buffer_memory_barriers[1].size = sizeof(uint32_t);
                ++buffer_memory_barriers_count;
            }

            DispatchCmdPipelineBarrier(cb_state.VkHandle(), VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
                                       VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, buffer_memory_barriers_count,
                                       buffer_memory_barriers.data(), 0, nullptr);
        }
    };
    cb_state.per_render_pass_validation_commands.emplace_back(std::move(validation_cmd));

    const uint32_t label_command_i =
        !cb_state.GetLabelCommands().empty() ? uint32_t(cb_state.GetLabelCommands().size() - 1) : vvl::kU32Max;
    CommandBuffer::ErrorLoggerFunc error_logger = [loc, vuid_oob_index, draw_buffer, draw_buffer_offset, draw_cmds_byte_stride,
                                                   index_buffer_binding = cb_state.index_buffer_binding,
                                                   label_command_i](Validator &gpuav, const CommandBuffer &cb_state,
                                                                    const uint32_t *error_record, const LogObjectList &objlist,
                                                                    const std::vector<std::string> &initial_label_stack) {
        bool skip = false;

        using namespace glsl;

        switch (error_record[kHeaderErrorSubCodeOffset]) {
            case kErrorSubCode_OobIndexBuffer: {
                const uint32_t draw_i = error_record[kPreActionParamOffset_0];
                const uint32_t first_index = error_record[kPreActionParamOffset_1];
                const uint32_t index_count = error_record[kPreActionParamOffset_2];
                const uint32_t highest_accessed_index = first_index + index_count;
                const uint32_t index_bits_size = GetIndexBitsSize(index_buffer_binding.index_type);
                const uint32_t max_indices_in_buffer = static_cast<uint32_t>(index_buffer_binding.size / (index_bits_size / 8u));

                std::string debug_region_name = cb_state.GetDebugLabelRegion(label_command_i, initial_label_stack);
                Location loc_with_debug_region(loc, debug_region_name);
                skip |= gpuav.LogError(
                    vuid_oob_index, objlist, loc_with_debug_region,
                    "Index %" PRIu32 " is not within the bound index buffer. Computed from VkDrawIndexedIndirectCommand[%" PRIu32
                    "] (.firstIndex = %" PRIu32 ", .indexCount = %" PRIu32
                    "), stored in %s\n"

                    "Index buffer binding info:\n"
                    "- Buffer: %s\n"
                    "- Index type: %s\n"
                    "- Binding offset: %" PRIu64
                    "\n"
                    "- Binding size: %" PRIu64 " bytes (or %" PRIu32
                    " %s)\n"

                    "Supplied buffer parameters in indirect command: offset = %" PRIu64 ", stride = %" PRIu32 " bytes.",
                    // OOB index info
                    highest_accessed_index, draw_i, first_index, index_count, gpuav.FormatHandle(draw_buffer).c_str(),

                    // Index buffer binding info
                    gpuav.FormatHandle(index_buffer_binding.buffer).c_str(), string_VkIndexType(index_buffer_binding.index_type),
                    index_buffer_binding.offset, index_buffer_binding.size, max_indices_in_buffer,
                    string_VkIndexType(index_buffer_binding.index_type),

                    // VkDrawIndexedIndirectCommand info
                    draw_buffer_offset, draw_cmds_byte_stride);
                break;
            }

            default:
                assert(false);
                return skip;
        }

        return skip;
    };

    cb_state.per_command_error_loggers.emplace_back(std::move(error_logger));
}

struct DrawIndexedIndirectVertexBufferShader {
    static size_t GetSpirvSize() { return cmd_validation_draw_indexed_indirect_vertex_buffer_comp_size * sizeof(uint32_t); }
    static const uint32_t *GetSpirv() { return cmd_validation_draw_indexed_indirect_vertex_buffer_comp; }

    static const uint32_t desc_set_id = gpuav::glsl::kDiagPerCmdDescriptorSet;

    glsl::DrawIndexedIndirectVertexBufferPushData push_constants{};
    BoundStorageBuffer draw_buffer_binding = {gpuav::glsl::kPreDrawBinding_IndirectBuffer};
    BoundStorageBuffer count_buffer_binding = {gpuav::glsl::kPreDrawBinding_CountBuffer};
    BoundStorageBuffer index_buffer_binding = {gpuav::glsl::kPreDrawBinding_IndexBuffer};

    static std::vector<VkDescriptorSetLayoutBinding> GetDescriptorSetLayoutBindings() {
        std::vector<VkDescriptorSetLayoutBinding> bindings = {
            {gpuav::glsl::kPreDrawBinding_IndirectBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT,
             nullptr},
            {gpuav::glsl::kPreDrawBinding_CountBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
            {gpuav::glsl::kPreDrawBinding_IndexBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}};

        return bindings;
    }

    std::vector<VkWriteDescriptorSet> GetDescriptorWrites(VkDescriptorSet desc_set) const {
        std::vector<VkWriteDescriptorSet> desc_writes(3);

        desc_writes[0] = vku::InitStructHelper();
        desc_writes[0].dstSet = desc_set;
        desc_writes[0].dstBinding = draw_buffer_binding.binding;
        desc_writes[0].dstArrayElement = 0;
        desc_writes[0].descriptorCount = 1;
        desc_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
        desc_writes[0].pBufferInfo = &draw_buffer_binding.info;

        desc_writes[1] = vku::InitStructHelper();
        desc_writes[1].dstSet = desc_set;
        desc_writes[1].dstBinding = count_buffer_binding.binding;
        desc_writes[1].dstArrayElement = 0;
        desc_writes[1].descriptorCount = 1;
        desc_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
        desc_writes[1].pBufferInfo = &count_buffer_binding.info;

        desc_writes[2] = vku::InitStructHelper();
        desc_writes[2].dstSet = desc_set;
        desc_writes[2].dstBinding = index_buffer_binding.binding;
        desc_writes[2].dstArrayElement = 0;
        desc_writes[2].descriptorCount = 1;
        desc_writes[2].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
        desc_writes[2].pBufferInfo = &index_buffer_binding.info;

        return desc_writes;
    }
};

void DrawIndexedIndirectVertexBuffer(Validator &gpuav, CommandBuffer &cb_state, const Location &loc, VkBuffer draw_buffer,
                                     VkDeviceSize draw_buffer_offset, uint32_t draw_cmds_byte_stride, uint32_t draw_count,
                                     VkBuffer count_buffer, VkDeviceSize count_buffer_offset, const char *vuid_oob_vertex) {
    if (!gpuav.gpuav_settings.validate_index_buffers) {
        return;
    }

    if (gpuav.enabled_features.robustBufferAccess) {
        return;
    }

    if (!cb_state.IsPrimary()) {
        // TODO Unhandled for now. Potential issues with accessing the right vertex buffers
        // in secondary command buffers
        return;
    }

    if (!cb_state.index_buffer_binding.buffer) {
        return;
    }

    const std::optional<SmallestVertexBufferBinding> smallest_vertex_buffer_binding = SmallestVertexAttributesCount(cb_state);
    if (!smallest_vertex_buffer_binding.has_value()) {
        return;
    }

    CommandBuffer::ValidationCommandFunc validation_cmd =
        [index_buffer_binding = cb_state.index_buffer_binding, smallest_vertex_buffer_binding = *smallest_vertex_buffer_binding,
         draw_buffer, draw_buffer_offset, draw_cmds_byte_stride, draw_count, count_buffer, count_buffer_offset,
         draw_i = cb_state.draw_index, error_logger_i = uint32_t(cb_state.per_command_error_loggers.size()),
         loc](Validator &gpuav, CommandBuffer &cb_state) {
            SharedDrawValidationResources &shared_draw_validation_resources =
                gpuav.shared_resources_manager.Get<SharedDrawValidationResources>(gpuav, loc);
            if (!shared_draw_validation_resources.valid) return;
            ComputeValidationPipeline<DrawIndexedIndirectVertexBufferShader> &validation_pipeline =
                gpuav.shared_resources_manager.Get<ComputeValidationPipeline<DrawIndexedIndirectVertexBufferShader>>(
                    gpuav, loc, cb_state.GetErrorLoggingDescSetLayout());
            if (!validation_pipeline.valid) return;

            const uint32_t index_bits_size = GetIndexBitsSize(index_buffer_binding.index_type);
            const uint32_t max_indices_in_buffer = static_cast<uint32_t>(index_buffer_binding.size / (index_bits_size / 8u));

            {
                DrawIndexedIndirectVertexBufferShader shader_resources;
                if (count_buffer != VK_NULL_HANDLE) {
                    shader_resources.push_constants.flags |= glsl::kIndexedIndirectDrawFlags_DrawCountFromBuffer;
                    shader_resources.count_buffer_binding.info = {count_buffer, 0, sizeof(uint32_t)};
                    shader_resources.push_constants.count_buffer_dwords_offset = (uint32_t)count_buffer_offset / sizeof(uint32_t);
                } else {
                    shader_resources.count_buffer_binding.info = {shared_draw_validation_resources.dummy_buffer.VkHandle(), 0,
                                                                  VK_WHOLE_SIZE};
                }

                shader_resources.push_constants.index_width = index_bits_size;
                shader_resources.push_constants.draw_cmds_stride_dwords = draw_cmds_byte_stride / sizeof(uint32_t);
                shader_resources.push_constants.bound_index_buffer_indices_count = max_indices_in_buffer;
                shader_resources.push_constants.cpu_draw_count = draw_count;

                shader_resources.push_constants.smallest_vertex_attributes_count =
                    static_cast<uint32_t>(smallest_vertex_buffer_binding.smallest_vertex_attributes_count);

                shader_resources.draw_buffer_binding.info = {draw_buffer, 0, VK_WHOLE_SIZE};
                shader_resources.push_constants.draw_indexed_indirect_cmds_buffer_dwords_offset =
                    (uint32_t)draw_buffer_offset / sizeof(uint32_t);
                shader_resources.index_buffer_binding.info = {index_buffer_binding.buffer, 0,
                                                              index_buffer_binding.offset + index_buffer_binding.size};
                shader_resources.push_constants.index_buffer_dwords_offset =
                    (uint32_t)index_buffer_binding.offset / sizeof(uint32_t);

                validation_pipeline.BindShaderResources(gpuav, cb_state, draw_i, error_logger_i, shader_resources);
            }

            {
                DispatchCmdBindPipeline(cb_state.VkHandle(), VK_PIPELINE_BIND_POINT_COMPUTE, validation_pipeline.pipeline);

                // Dispatch as many draws as there are indices in index buffer.
                // Each shader invocation will inspect one index, for all draw commands.
                // Shader is in charge of performing validation only for indices within the supplied ranges.
                constexpr uint32_t work_group_size = 64;
                const uint32_t indices_to_check = max_indices_in_buffer;
                const uint32_t work_group_count =
                    indices_to_check / work_group_size + uint32_t(indices_to_check % work_group_size != 0);
                VVL_TracyPlot("gpuav::valcmd::DrawIndexedIndirectVertexBuffer Dispatch size", int64_t(work_group_count));
                DispatchCmdDispatch(cb_state.VkHandle(), work_group_count, 1, 1);
                // synchronize draw buffer validation (read) against subsequent writes
                std::array<VkBufferMemoryBarrier, 3> buffer_memory_barriers = {};
                uint32_t buffer_memory_barriers_count = 2;
                buffer_memory_barriers[0] = vku::InitStructHelper();
                buffer_memory_barriers[0].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
                buffer_memory_barriers[0].dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
                buffer_memory_barriers[0].buffer = draw_buffer;
                buffer_memory_barriers[0].offset = draw_buffer_offset;
                buffer_memory_barriers[0].size = VK_WHOLE_SIZE;

                buffer_memory_barriers[1] = vku::InitStructHelper();
                buffer_memory_barriers[1].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
                buffer_memory_barriers[1].dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
                buffer_memory_barriers[1].buffer = index_buffer_binding.buffer;
                buffer_memory_barriers[1].offset = index_buffer_binding.offset;
                buffer_memory_barriers[1].size = index_buffer_binding.size;

                if (count_buffer) {
                    buffer_memory_barriers[2] = vku::InitStructHelper();
                    buffer_memory_barriers[2].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
                    buffer_memory_barriers[2].dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
                    buffer_memory_barriers[2].buffer = count_buffer;
                    buffer_memory_barriers[2].offset = count_buffer_offset;
                    buffer_memory_barriers[2].size = sizeof(uint32_t);
                    ++buffer_memory_barriers_count;
                }

                DispatchCmdPipelineBarrier(cb_state.VkHandle(), VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
                                           VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, buffer_memory_barriers_count,
                                           buffer_memory_barriers.data(), 0, nullptr);
            }
        };
    cb_state.per_render_pass_validation_commands.emplace_back(std::move(validation_cmd));

    const uint32_t label_command_i =
        !cb_state.GetLabelCommands().empty() ? uint32_t(cb_state.GetLabelCommands().size() - 1) : vvl::kU32Max;
    CommandBuffer::ErrorLoggerFunc error_logger =
        [loc, vuid_oob_vertex, draw_buffer, smallest_vertex_buffer_binding = *smallest_vertex_buffer_binding,
         index_buffer_binding = cb_state.index_buffer_binding,
         label_command_i](Validator &gpuav, const CommandBuffer &cb_state, const uint32_t *error_record,
                          const LogObjectList &objlist, const std::vector<std::string> &initial_label_stack) {
            bool skip = false;

            using namespace glsl;

            switch (error_record[kHeaderErrorSubCodeOffset]) {
                case kErrorSubCode_OobVertexBuffer: {
                    const uint32_t draw_i = error_record[kPreActionParamOffset_0];
                    const uint32_t index_buffer_offset = error_record[kPreActionParamOffset_1];
                    const int32_t vertex_offset = static_cast<int32_t>(error_record[kPreActionParamOffset_2]);
                    const uint32_t vertex_index = error_record[kPreActionParamOffset_3];
                    const uint32_t index_buffer_value = static_cast<uint32_t>(int32_t(vertex_index) - vertex_offset);
                    const uint32_t index_bits_size = GetIndexBitsSize(index_buffer_binding.index_type);
                    const uint32_t max_indices_in_buffer =
                        static_cast<uint32_t>(index_buffer_binding.size / (index_bits_size / 8u));

                    std::string debug_region_name = cb_state.GetDebugLabelRegion(label_command_i, initial_label_stack);
                    Location loc_with_debug_region(loc, debug_region_name);
                    skip |= gpuav.LogError(
                        vuid_oob_vertex, objlist, loc_with_debug_region,
                        "Vertex index %" PRIu32
                        " is not within the smallest bound vertex buffer. Computed from VkDrawIndexedIndirectCommand[ %" PRIu32
                        " ], stored in %s.\n"
                        "index_buffer[ %" PRIu32 " ] (%" PRIu32 ") + vertexOffset (%" PRIi32 ") = Vertex index %" PRIu32
                        "\n"

                        "Smallest vertex buffer binding info, causing OOB access:\n"
                        "- Buffer: %s\n"
                        "- Binding: %" PRIu32
                        "\n"
                        "- Binding size (effective): %" PRIu64
                        " bytes\n"
                        "- Binding offset: %" PRIu64
                        " bytes\n"
                        "- Binding stride: %" PRIu64
                        " bytes\n"
                        "- Vertices count: %" PRIu64
                        "\n"

                        "At least the following vertex attribute caused OOB access:\n"
                        "- location: %" PRIu32
                        "\n"
                        "- binding: %" PRIu32
                        "\n"
                        "- format: %s\n"
                        "- offset: %" PRIu32
                        " bytes\n"

                        "Index buffer binding info:\n"
                        "- Buffer: %s\n"
                        "- Index type: %s\n"
                        "- Binding offset: %" PRIu64
                        " bytes\n"
                        "- Binding size: %" PRIu64 " bytes (or %" PRIu32
                        " %s)\n"

                        "Note: Vertex buffer binding size is the effective, valid one, based on how the VkBuffer was created and "
                        "vertex buffer binding parameters. So it can be clamped up to 0 if binding was invalid.\n",
                        // OOB vertex index info
                        vertex_index, draw_i, gpuav.FormatHandle(draw_buffer).c_str(), index_buffer_offset, index_buffer_value,
                        vertex_offset, vertex_index,

                        // Vertex buffer binding info
                        gpuav.FormatHandle(smallest_vertex_buffer_binding.binding_info.buffer).c_str(),
                        smallest_vertex_buffer_binding.binding, smallest_vertex_buffer_binding.binding_info.effective_size,
                        smallest_vertex_buffer_binding.binding_info.offset, smallest_vertex_buffer_binding.binding_info.stride,
                        smallest_vertex_buffer_binding.smallest_vertex_attributes_count,

                        // Vertex Attribute info
                        smallest_vertex_buffer_binding.attribute.location, smallest_vertex_buffer_binding.attribute.binding,
                        string_VkFormat(smallest_vertex_buffer_binding.attribute.format),
                        smallest_vertex_buffer_binding.attribute.offset,

                        // Index buffer binding info
                        gpuav.FormatHandle(index_buffer_binding.buffer).c_str(),
                        string_VkIndexType(index_buffer_binding.index_type), index_buffer_binding.offset, index_buffer_binding.size,
                        max_indices_in_buffer, string_VkIndexType(index_buffer_binding.index_type));

                    break;
                }

                default:
                    assert(false);
                    return skip;
            }

            return skip;
        };

    cb_state.per_command_error_loggers.emplace_back(std::move(error_logger));
}

}  // namespace valcmd
}  // namespace gpuav
