/* Copyright (c) 2015-2021 The Khronos Group Inc.
 * Copyright (c) 2015-2021 Valve Corporation
 * Copyright (c) 2015-2021 LunarG, Inc.
 * Copyright (C) 2015-2021 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.
 *
 * Author: Courtney Goeltzenleuchter <courtneygo@google.com>
 * Author: Tobin Ehlis <tobine@google.com>
 * Author: Chris Forbes <chrisf@ijw.co.nz>
 * Author: Mark Lobodzinski <mark@lunarg.com>
 * Author: Dave Houlton <daveh@lunarg.com>
 * Author: John Zulauf <jzulauf@lunarg.com>
 * Author: Tobias Hector <tobias.hector@amd.com>
 */
#include "cmd_buffer_state.h"
#include "render_pass_state.h"
#include "state_tracker.h"
#include "image_state.h"

const char *CommandTypeString(CMD_TYPE type) {
    // Autogenerated as part of the command_validation.h codegen
    return kGeneratedCommandNameList[type];
}

VkDynamicState ConvertToDynamicState(CBStatusFlagBits flag) {
    switch (flag) {
        case CBSTATUS_LINE_WIDTH_SET:
            return VK_DYNAMIC_STATE_LINE_WIDTH;
        case CBSTATUS_DEPTH_BIAS_SET:
            return VK_DYNAMIC_STATE_DEPTH_BIAS;
        case CBSTATUS_BLEND_CONSTANTS_SET:
            return VK_DYNAMIC_STATE_BLEND_CONSTANTS;
        case CBSTATUS_DEPTH_BOUNDS_SET:
            return VK_DYNAMIC_STATE_DEPTH_BOUNDS;
        case CBSTATUS_STENCIL_READ_MASK_SET:
            return VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK;
        case CBSTATUS_STENCIL_WRITE_MASK_SET:
            return VK_DYNAMIC_STATE_STENCIL_WRITE_MASK;
        case CBSTATUS_STENCIL_REFERENCE_SET:
            return VK_DYNAMIC_STATE_STENCIL_REFERENCE;
        case CBSTATUS_VIEWPORT_SET:
            return VK_DYNAMIC_STATE_VIEWPORT;
        case CBSTATUS_SCISSOR_SET:
            return VK_DYNAMIC_STATE_SCISSOR;
        case CBSTATUS_EXCLUSIVE_SCISSOR_SET:
            return VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV;
        case CBSTATUS_SHADING_RATE_PALETTE_SET:
            return VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV;
        case CBSTATUS_LINE_STIPPLE_SET:
            return VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
        case CBSTATUS_VIEWPORT_W_SCALING_SET:
            return VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV;
        case CBSTATUS_CULL_MODE_SET:
            return VK_DYNAMIC_STATE_CULL_MODE_EXT;
        case CBSTATUS_FRONT_FACE_SET:
            return VK_DYNAMIC_STATE_FRONT_FACE_EXT;
        case CBSTATUS_PRIMITIVE_TOPOLOGY_SET:
            return VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT;
        case CBSTATUS_VIEWPORT_WITH_COUNT_SET:
            return VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT;
        case CBSTATUS_SCISSOR_WITH_COUNT_SET:
            return VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT;
        case CBSTATUS_VERTEX_INPUT_BINDING_STRIDE_SET:
            return VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT;
        case CBSTATUS_DEPTH_TEST_ENABLE_SET:
            return VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT;
        case CBSTATUS_DEPTH_WRITE_ENABLE_SET:
            return VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT;
        case CBSTATUS_DEPTH_COMPARE_OP_SET:
            return VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT;
        case CBSTATUS_DEPTH_BOUNDS_TEST_ENABLE_SET:
            return VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT;
        case CBSTATUS_STENCIL_TEST_ENABLE_SET:
            return VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT;
        case CBSTATUS_STENCIL_OP_SET:
            return VK_DYNAMIC_STATE_STENCIL_OP_EXT;
        case CBSTATUS_DISCARD_RECTANGLE_SET:
            return VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT;
        case CBSTATUS_SAMPLE_LOCATIONS_SET:
            return VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT;
        case CBSTATUS_COARSE_SAMPLE_ORDER_SET:
            return VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV;
        case CBSTATUS_PATCH_CONTROL_POINTS_SET:
            return VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT;
        case CBSTATUS_RASTERIZER_DISCARD_ENABLE_SET:
            return VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT;
        case CBSTATUS_DEPTH_BIAS_ENABLE_SET:
            return VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT;
        case CBSTATUS_LOGIC_OP_SET:
            return VK_DYNAMIC_STATE_LOGIC_OP_EXT;
        case CBSTATUS_PRIMITIVE_RESTART_ENABLE_SET:
            return VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT;
        case CBSTATUS_VERTEX_INPUT_SET:
            return VK_DYNAMIC_STATE_VERTEX_INPUT_EXT;
        default:
            // CBSTATUS_INDEX_BUFFER_BOUND is not in VkDynamicState
            return VK_DYNAMIC_STATE_MAX_ENUM;
    }
    return VK_DYNAMIC_STATE_MAX_ENUM;
}

CBStatusFlagBits ConvertToCBStatusFlagBits(VkDynamicState state) {
    switch (state) {
        case VK_DYNAMIC_STATE_VIEWPORT:
            return CBSTATUS_VIEWPORT_SET;
        case VK_DYNAMIC_STATE_SCISSOR:
            return CBSTATUS_SCISSOR_SET;
        case VK_DYNAMIC_STATE_LINE_WIDTH:
            return CBSTATUS_LINE_WIDTH_SET;
        case VK_DYNAMIC_STATE_DEPTH_BIAS:
            return CBSTATUS_DEPTH_BIAS_SET;
        case VK_DYNAMIC_STATE_BLEND_CONSTANTS:
            return CBSTATUS_BLEND_CONSTANTS_SET;
        case VK_DYNAMIC_STATE_DEPTH_BOUNDS:
            return CBSTATUS_DEPTH_BOUNDS_SET;
        case VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK:
            return CBSTATUS_STENCIL_READ_MASK_SET;
        case VK_DYNAMIC_STATE_STENCIL_WRITE_MASK:
            return CBSTATUS_STENCIL_WRITE_MASK_SET;
        case VK_DYNAMIC_STATE_STENCIL_REFERENCE:
            return CBSTATUS_STENCIL_REFERENCE_SET;
        case VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV:
            return CBSTATUS_VIEWPORT_W_SCALING_SET;
        case VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT:
            return CBSTATUS_DISCARD_RECTANGLE_SET;
        case VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT:
            return CBSTATUS_SAMPLE_LOCATIONS_SET;
        case VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV:
            return CBSTATUS_SHADING_RATE_PALETTE_SET;
        case VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV:
            return CBSTATUS_COARSE_SAMPLE_ORDER_SET;
        case VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV:
            return CBSTATUS_EXCLUSIVE_SCISSOR_SET;
        case VK_DYNAMIC_STATE_LINE_STIPPLE_EXT:
            return CBSTATUS_LINE_STIPPLE_SET;
        case VK_DYNAMIC_STATE_CULL_MODE_EXT:
            return CBSTATUS_CULL_MODE_SET;
        case VK_DYNAMIC_STATE_FRONT_FACE_EXT:
            return CBSTATUS_FRONT_FACE_SET;
        case VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT:
            return CBSTATUS_PRIMITIVE_TOPOLOGY_SET;
        case VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT:
            return CBSTATUS_VIEWPORT_WITH_COUNT_SET;
        case VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT:
            return CBSTATUS_SCISSOR_WITH_COUNT_SET;
        case VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT:
            return CBSTATUS_VERTEX_INPUT_BINDING_STRIDE_SET;
        case VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT:
            return CBSTATUS_DEPTH_TEST_ENABLE_SET;
        case VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT:
            return CBSTATUS_DEPTH_WRITE_ENABLE_SET;
        case VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT:
            return CBSTATUS_DEPTH_COMPARE_OP_SET;
        case VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT:
            return CBSTATUS_DEPTH_BOUNDS_TEST_ENABLE_SET;
        case VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT:
            return CBSTATUS_STENCIL_TEST_ENABLE_SET;
        case VK_DYNAMIC_STATE_STENCIL_OP_EXT:
            return CBSTATUS_STENCIL_OP_SET;
        case VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT:
            return CBSTATUS_PATCH_CONTROL_POINTS_SET;
        case VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT:
            return CBSTATUS_RASTERIZER_DISCARD_ENABLE_SET;
        case VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT:
            return CBSTATUS_DEPTH_BIAS_ENABLE_SET;
        case VK_DYNAMIC_STATE_LOGIC_OP_EXT:
            return CBSTATUS_LOGIC_OP_SET;
        case VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT:
            return CBSTATUS_PRIMITIVE_RESTART_ENABLE_SET;
        case VK_DYNAMIC_STATE_VERTEX_INPUT_EXT:
            return CBSTATUS_VERTEX_INPUT_SET;
        default:
            return CBSTATUS_NONE;
    }
    return CBSTATUS_NONE;
}

CMD_BUFFER_STATE::CMD_BUFFER_STATE(ValidationStateTracker *dd, VkCommandBuffer cb, const VkCommandBufferAllocateInfo *pCreateInfo,
                                   std::shared_ptr<COMMAND_POOL_STATE> &pool)
    : REFCOUNTED_NODE(cb, kVulkanObjectTypeCommandBuffer),
      createInfo(*pCreateInfo),
      command_pool(pool),
      dev_data(dd),
      unprotected(pool->unprotected) {
    Reset();
}

// Get the image viewstate for a given framebuffer attachment
IMAGE_VIEW_STATE *CMD_BUFFER_STATE::GetActiveAttachmentImageViewState(uint32_t index) {
    assert(active_attachments && index != VK_ATTACHMENT_UNUSED && (index < active_attachments->size()));
    return active_attachments->at(index);
}

// Get the image viewstate for a given framebuffer attachment
const IMAGE_VIEW_STATE *CMD_BUFFER_STATE::GetActiveAttachmentImageViewState(uint32_t index) const {
    if (!active_attachments || index == VK_ATTACHMENT_UNUSED || (index >= active_attachments->size())) {
        return nullptr;
    }
    return active_attachments->at(index);
}

void CMD_BUFFER_STATE::AddChild(BASE_NODE *child_node) {
    if (child_node->AddParent(this)) {
        object_bindings.insert(child_node->Handle());
    }
}

void CMD_BUFFER_STATE::RemoveChild(BASE_NODE *child_node) {
    child_node->RemoveParent(this);
    object_bindings.erase(child_node->Handle());
}

// Reset the command buffer state
//  Maintain the createInfo and set state to CB_NEW, but clear all other state
void CMD_BUFFER_STATE::Reset() {
    ResetUse();
    // Reset CB state (note that createInfo is not cleared)
    memset(&beginInfo, 0, sizeof(VkCommandBufferBeginInfo));
    memset(&inheritanceInfo, 0, sizeof(VkCommandBufferInheritanceInfo));
    hasDrawCmd = false;
    hasTraceRaysCmd = false;
    hasBuildAccelerationStructureCmd = false;
    hasDispatchCmd = false;
    state = CB_NEW;
    commandCount = 0;
    submitCount = 0;
    image_layout_change_count = 1;  // Start at 1. 0 is insert value for validation cache versions, s.t. new == dirty
    status = 0;
    static_status = 0;
    inheritedViewportDepths.clear();
    usedViewportScissorCount = 0;
    pipelineStaticViewportCount = 0;
    pipelineStaticScissorCount = 0;
    viewportMask = 0;
    viewportWithCountMask = 0;
    viewportWithCountCount = 0;
    scissorMask = 0;
    scissorWithCountMask = 0;
    scissorWithCountCount = 0;
    trashedViewportMask = 0;
    trashedScissorMask = 0;
    trashedViewportCount = false;
    trashedScissorCount = false;
    usedDynamicViewportCount = false;
    usedDynamicScissorCount = false;
    primitiveTopology = VK_PRIMITIVE_TOPOLOGY_MAX_ENUM;

    activeRenderPassBeginInfo = safe_VkRenderPassBeginInfo();
    activeRenderPass = nullptr;
    active_attachments = nullptr;
    active_subpasses = nullptr;
    attachments_view_states.clear();
    activeSubpassContents = VK_SUBPASS_CONTENTS_INLINE;
    activeSubpass = 0;
    broken_bindings.clear();
    waitedEvents.clear();
    events.clear();
    writeEventsBeforeWait.clear();
    activeQueries.clear();
    startedQueries.clear();
    image_layout_map.clear();
    current_vertex_buffer_binding_info.vertex_buffer_bindings.clear();
    vertex_buffer_used = false;
    primaryCommandBuffer = VK_NULL_HANDLE;

    linkedCommandBuffers.clear();
    // Remove reverse command buffer links.
    Invalidate(true);

    queue_submit_functions.clear();
    queue_submit_functions_after_render_pass.clear();
    cmd_execute_commands_functions.clear();
    eventUpdates.clear();
    queryUpdates.clear();

    // Remove object bindings
    for (const auto &obj : object_bindings) {
        if (obj.node) {
            obj.node->RemoveParent(this);
        }
    }
    object_bindings.clear();

    for (auto &item : lastBound) {
        item.Reset();
    }
    // Remove this cmdBuffer's reference from each FrameBuffer's CB ref list
    for (auto &framebuffer : framebuffers) {
        framebuffer->RemoveParent(this);
    }
    framebuffers.clear();
    activeFramebuffer = VK_NULL_HANDLE;
    index_buffer_binding.reset();

    qfo_transfer_image_barriers.Reset();
    qfo_transfer_buffer_barriers.Reset();

    // Clean up the label data
    debug_label.Reset();
    validate_descriptorsets_in_queuesubmit.clear();

    // Best practices info
    small_indexed_draw_call_count = 0;

    transform_feedback_active = false;

    // Remove object bindings
    for (const auto &obj : object_bindings) {
        BASE_NODE *base_obj = obj.node;
        if (base_obj) RemoveChild(base_obj);
    }
    object_bindings.clear();

    // Clean up the label data
    ResetCmdDebugUtilsLabel(dev_data->report_data, commandBuffer());

    if (dev_data->command_buffer_reset_callback) {
        (*dev_data->command_buffer_reset_callback)(commandBuffer());
    }
}

// Track which resources are in-flight by atomically incrementing their "in_use" count
void CMD_BUFFER_STATE::IncrementResources() {
    submitCount++;

    // TODO : We should be able to remove the NULL look-up checks from the code below as long as
    //  all the corresponding cases are verified to cause CB_INVALID state and the CB_INVALID state
    //  should then be flagged prior to calling this function
    for (auto event : writeEventsBeforeWait) {
        auto event_state = dev_data->GetEventState(event);
        if (event_state) event_state->write_in_use++;
    }
}

// Discussed in details in https://github.com/KhronosGroup/Vulkan-Docs/issues/1081
// Internal discussion and CTS were written to prove that this is not called after an incompatible vkCmdBindPipeline
// "Binding a pipeline with a layout that is not compatible with the push constant layout does not disturb the push constant values"
//
// vkCmdBindDescriptorSet has nothing to do with push constants and don't need to call this after neither
//
// Part of this assumes apps at draw/dispath/traceRays/etc time will have it properly compatabile or else other VU will be triggered
void CMD_BUFFER_STATE::ResetPushConstantDataIfIncompatible(const PIPELINE_LAYOUT_STATE *pipeline_layout_state) {
    if (pipeline_layout_state == nullptr) {
        return;
    }
    if (push_constant_data_ranges == pipeline_layout_state->push_constant_ranges) {
        return;
    }

    push_constant_data_ranges = pipeline_layout_state->push_constant_ranges;
    push_constant_data.clear();
    push_constant_data_update.clear();
    uint32_t size_needed = 0;
    for (const auto &push_constant_range : *push_constant_data_ranges) {
        auto size = push_constant_range.offset + push_constant_range.size;
        size_needed = std::max(size_needed, size);

        auto stage_flags = push_constant_range.stageFlags;
        uint32_t bit_shift = 0;
        while (stage_flags) {
            if (stage_flags & 1) {
                VkShaderStageFlagBits flag = static_cast<VkShaderStageFlagBits>(1 << bit_shift);
                const auto it = push_constant_data_update.find(flag);

                if (it != push_constant_data_update.end()) {
                    if (it->second.size() < push_constant_range.offset) {
                        it->second.resize(push_constant_range.offset, PC_Byte_Not_Set);
                    }
                    if (it->second.size() < size) {
                        it->second.resize(size, PC_Byte_Not_Updated);
                    }
                } else {
                    std::vector<uint8_t> bytes;
                    bytes.resize(push_constant_range.offset, PC_Byte_Not_Set);
                    bytes.resize(size, PC_Byte_Not_Updated);
                    push_constant_data_update[flag] = bytes;
                }
            }
            stage_flags = stage_flags >> 1;
            ++bit_shift;
        }
    }
    push_constant_data.resize(size_needed, 0);
}

void CMD_BUFFER_STATE::Destroy() {
    // Allow any derived class to clean up command buffer state
    if (dev_data->command_buffer_reset_callback) {
        (*dev_data->command_buffer_reset_callback)(commandBuffer());
    }
    if (dev_data->command_buffer_free_callback) {
        (*dev_data->command_buffer_free_callback)(commandBuffer());
    }

    // Remove the cb debug labels
    EraseCmdDebugUtilsLabel(dev_data->report_data, commandBuffer());
    Reset();
    BASE_NODE::Destroy();
}

void CMD_BUFFER_STATE::NotifyInvalidate(const LogObjectList &invalid_handles, bool unlink) {
    if (state == CB_RECORDING) {
        state = CB_INVALID_INCOMPLETE;
    } else if (state == CB_RECORDED) {
        state = CB_INVALID_COMPLETE;
    }
    assert(!invalid_handles.object_list.empty());
    broken_bindings.emplace(invalid_handles.object_list[0], invalid_handles);

    if (unlink) {
        for (auto &obj : invalid_handles.object_list) {
            object_bindings.erase(obj);
            if (obj.type == kVulkanObjectTypeCommandBuffer) {
                linkedCommandBuffers.erase(static_cast<CMD_BUFFER_STATE *>(obj.node));
            }
        }
    }
    BASE_NODE::NotifyInvalidate(invalid_handles, unlink);
}

// The const variant only need the image as it is the key for the map
const ImageSubresourceLayoutMap *CMD_BUFFER_STATE::GetImageSubresourceLayoutMap(VkImage image) const {
    auto it = image_layout_map.find(image);
    if (it == image_layout_map.cend()) {
        return nullptr;
    }
    return &it->second;
}

// The non-const variant only needs the image state, as the factory requires it to construct a new entry
ImageSubresourceLayoutMap *CMD_BUFFER_STATE::GetImageSubresourceLayoutMap(const IMAGE_STATE &image_state) {
    auto &layout_map = image_layout_map[image_state.image()];
    if (!layout_map) {
        // Was an empty slot... fill it in.
        layout_map.emplace(image_state);
    }
    return &layout_map;
}

static bool SetQueryState(QueryObject object, QueryState value, QueryMap *localQueryToStateMap) {
    (*localQueryToStateMap)[object] = value;
    return false;
}

void CMD_BUFFER_STATE::BeginQuery(const QueryObject &query_obj) {
    activeQueries.insert(query_obj);
    startedQueries.insert(query_obj);
    queryUpdates.emplace_back([query_obj](const ValidationStateTracker *device_data, bool do_validate,
                                          VkQueryPool &firstPerfQueryPool, uint32_t perfQueryPass, QueryMap *localQueryToStateMap) {
        SetQueryState(QueryObject(query_obj, perfQueryPass), QUERYSTATE_RUNNING, localQueryToStateMap);
        return false;
    });
}

void CMD_BUFFER_STATE::EndQuery(const QueryObject &query_obj) {
    activeQueries.erase(query_obj);
    queryUpdates.emplace_back([query_obj](const ValidationStateTracker *device_data, bool do_validate,
                                          VkQueryPool &firstPerfQueryPool, uint32_t perfQueryPass, QueryMap *localQueryToStateMap) {
        return SetQueryState(QueryObject(query_obj, perfQueryPass), QUERYSTATE_ENDED, localQueryToStateMap);
    });
}

static bool SetQueryStateMulti(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, uint32_t perfPass, QueryState value,
                               QueryMap *localQueryToStateMap) {
    for (uint32_t i = 0; i < queryCount; i++) {
        QueryObject object = QueryObject(QueryObject(queryPool, firstQuery + i), perfPass);
        (*localQueryToStateMap)[object] = value;
    }
    return false;
}

void CMD_BUFFER_STATE::EndQueries(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount) {
    for (uint32_t slot = firstQuery; slot < (firstQuery + queryCount); slot++) {
        QueryObject query = {queryPool, slot};
        activeQueries.erase(query);
    }
    queryUpdates.emplace_back([queryPool, firstQuery, queryCount](const ValidationStateTracker *device_data, bool do_validate,
                                                                  VkQueryPool &firstPerfQueryPool, uint32_t perfQueryPass,
                                                                  QueryMap *localQueryToStateMap) {
        return SetQueryStateMulti(queryPool, firstQuery, queryCount, perfQueryPass, QUERYSTATE_RESET, localQueryToStateMap);
    });
}

void CMD_BUFFER_STATE::ResetQueryPool(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount) {
    for (uint32_t slot = firstQuery; slot < (firstQuery + queryCount); slot++) {
        QueryObject query = {queryPool, slot};
        resetQueries.insert(query);
    }

    queryUpdates.emplace_back([queryPool, firstQuery, queryCount](const ValidationStateTracker *device_data, bool do_validate,
                                                                  VkQueryPool &firstPerfQueryPool, uint32_t perfQueryPass,
                                                                  QueryMap *localQueryToStateMap) {
        return SetQueryStateMulti(queryPool, firstQuery, queryCount, perfQueryPass, QUERYSTATE_RESET, localQueryToStateMap);
    });
}

void UpdateSubpassAttachments(const safe_VkSubpassDescription2 &subpass, std::vector<SUBPASS_INFO> &subpasses) {
    for (uint32_t index = 0; index < subpass.inputAttachmentCount; ++index) {
        const uint32_t attachment_index = subpass.pInputAttachments[index].attachment;
        if (attachment_index != VK_ATTACHMENT_UNUSED) {
            subpasses[attachment_index].used = true;
            subpasses[attachment_index].usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
            subpasses[attachment_index].layout = subpass.pInputAttachments[index].layout;
        }
    }

    for (uint32_t index = 0; index < subpass.colorAttachmentCount; ++index) {
        const uint32_t attachment_index = subpass.pColorAttachments[index].attachment;
        if (attachment_index != VK_ATTACHMENT_UNUSED) {
            subpasses[attachment_index].used = true;
            subpasses[attachment_index].usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
            subpasses[attachment_index].layout = subpass.pColorAttachments[index].layout;
        }
        if (subpass.pResolveAttachments) {
            const uint32_t attachment_index2 = subpass.pResolveAttachments[index].attachment;
            if (attachment_index2 != VK_ATTACHMENT_UNUSED) {
                subpasses[attachment_index2].used = true;
                subpasses[attachment_index2].usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
                subpasses[attachment_index2].layout = subpass.pResolveAttachments[index].layout;
            }
        }
    }

    if (subpass.pDepthStencilAttachment) {
        const uint32_t attachment_index = subpass.pDepthStencilAttachment->attachment;
        if (attachment_index != VK_ATTACHMENT_UNUSED) {
            subpasses[attachment_index].used = true;
            subpasses[attachment_index].usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
            subpasses[attachment_index].layout = subpass.pDepthStencilAttachment->layout;
        }
    }
}

void CMD_BUFFER_STATE::UpdateAttachmentsView(const VkRenderPassBeginInfo *pRenderPassBegin) {
    auto &attachments = *(active_attachments.get());
    const bool imageless = (activeFramebuffer->createInfo.flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT) ? true : false;
    const VkRenderPassAttachmentBeginInfo *attachment_info_struct = nullptr;
    if (pRenderPassBegin) attachment_info_struct = LvlFindInChain<VkRenderPassAttachmentBeginInfo>(pRenderPassBegin->pNext);

    for (uint32_t i = 0; i < attachments.size(); ++i) {
        if (imageless) {
            if (attachment_info_struct && i < attachment_info_struct->attachmentCount) {
                auto res =
                    attachments_view_states.insert(dev_data->GetShared<IMAGE_VIEW_STATE>(attachment_info_struct->pAttachments[i]));
                attachments[i] = res.first->get();
            }
        } else {
            auto res = attachments_view_states.insert(activeFramebuffer->attachments_view_state[i]);
            attachments[i] = res.first->get();
        }
    }
}

void CMD_BUFFER_STATE::BeginRenderPass(CMD_TYPE cmd_type, const VkRenderPassBeginInfo *pRenderPassBegin,
                                       const VkSubpassContents contents) {
    RecordCmd(cmd_type);
    activeFramebuffer = dev_data->GetShared<FRAMEBUFFER_STATE>(pRenderPassBegin->framebuffer);
    activeRenderPass = dev_data->GetShared<RENDER_PASS_STATE>(pRenderPassBegin->renderPass);
    activeRenderPassBeginInfo = safe_VkRenderPassBeginInfo(pRenderPassBegin);
    activeSubpass = 0;
    activeSubpassContents = contents;

    // Connect this RP to cmdBuffer
    if (!dev_data->disabled[command_buffer_state] && activeRenderPass) {
        AddChild(activeRenderPass.get());
    }

    auto chained_device_group_struct = LvlFindInChain<VkDeviceGroupRenderPassBeginInfo>(pRenderPassBegin->pNext);
    if (chained_device_group_struct) {
        active_render_pass_device_mask = chained_device_group_struct->deviceMask;
    } else {
        active_render_pass_device_mask = initial_device_mask;
    }

    active_subpasses = nullptr;
    active_attachments = nullptr;

    if (activeFramebuffer) {
        framebuffers.insert(activeFramebuffer);

        // Set cb_state->active_subpasses
        active_subpasses = std::make_shared<std::vector<SUBPASS_INFO>>(activeFramebuffer->createInfo.attachmentCount);
        const auto &subpass = activeRenderPass->createInfo.pSubpasses[activeSubpass];
        UpdateSubpassAttachments(subpass, *active_subpasses);

        // Set cb_state->active_attachments & cb_state->attachments_view_states
        active_attachments = std::make_shared<std::vector<IMAGE_VIEW_STATE *>>(activeFramebuffer->createInfo.attachmentCount);
        UpdateAttachmentsView(pRenderPassBegin);

        // Connect this framebuffer and its children to this cmdBuffer
        AddChild(activeFramebuffer.get());
    }
}

void CMD_BUFFER_STATE::NextSubpass(CMD_TYPE cmd_type, VkSubpassContents contents) {
    RecordCmd(cmd_type);
    activeSubpass++;
    activeSubpassContents = contents;

    // Update cb_state->active_subpasses
    if (activeRenderPass && activeFramebuffer) {
        active_subpasses = nullptr;
        active_subpasses = std::make_shared<std::vector<SUBPASS_INFO>>(activeFramebuffer->createInfo.attachmentCount);

        const auto &subpass = activeRenderPass->createInfo.pSubpasses[activeSubpass];
        UpdateSubpassAttachments(subpass, *active_subpasses);
    }
}

void CMD_BUFFER_STATE::EndRenderPass(CMD_TYPE cmd_type) {
    RecordCmd(cmd_type);
    activeRenderPass = nullptr;
    active_attachments = nullptr;
    active_subpasses = nullptr;
    activeSubpass = 0;
    activeFramebuffer = VK_NULL_HANDLE;
}

void CMD_BUFFER_STATE::Begin(const VkCommandBufferBeginInfo *pBeginInfo) {
    if (CB_RECORDED == state || CB_INVALID_COMPLETE == state) {
        Reset();
    }
    // Set updated state here in case implicit reset occurs above
    state = CB_RECORDING;
    beginInfo = *pBeginInfo;
    if (beginInfo.pInheritanceInfo && (createInfo.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY)) {
        inheritanceInfo = *(beginInfo.pInheritanceInfo);
        beginInfo.pInheritanceInfo = &inheritanceInfo;
        // If we are a secondary command-buffer and inheriting.  Update the items we should inherit.
        if ((createInfo.level != VK_COMMAND_BUFFER_LEVEL_PRIMARY) &&
            (beginInfo.flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
            activeRenderPass = dev_data->GetShared<RENDER_PASS_STATE>(beginInfo.pInheritanceInfo->renderPass);
            activeSubpass = beginInfo.pInheritanceInfo->subpass;

            if (beginInfo.pInheritanceInfo->framebuffer) {
                activeFramebuffer = dev_data->GetShared<FRAMEBUFFER_STATE>(beginInfo.pInheritanceInfo->framebuffer);
                active_subpasses = nullptr;
                active_attachments = nullptr;

                if (activeFramebuffer) {
                    framebuffers.insert(activeFramebuffer);

                    // Set active_subpasses
                    active_subpasses = std::make_shared<std::vector<SUBPASS_INFO>>(activeFramebuffer->createInfo.attachmentCount);
                    const auto &subpass = activeRenderPass->createInfo.pSubpasses[activeSubpass];
                    UpdateSubpassAttachments(subpass, *active_subpasses);

                    // Set active_attachments & attachments_view_states
                    active_attachments =
                        std::make_shared<std::vector<IMAGE_VIEW_STATE *>>(activeFramebuffer->createInfo.attachmentCount);
                    UpdateAttachmentsView(nullptr);

                    // Connect this framebuffer and its children to this cmdBuffer
                    if (!dev_data->disabled[command_buffer_state]) {
                        AddChild(activeFramebuffer.get());
                    }
                }
            }

            // Check for VkCommandBufferInheritanceViewportScissorInfoNV (VK_NV_inherited_viewport_scissor)
            auto p_inherited_viewport_scissor_info =
                LvlFindInChain<VkCommandBufferInheritanceViewportScissorInfoNV>(beginInfo.pInheritanceInfo->pNext);
            if (p_inherited_viewport_scissor_info != nullptr && p_inherited_viewport_scissor_info->viewportScissor2D) {
                auto pViewportDepths = p_inherited_viewport_scissor_info->pViewportDepths;
                inheritedViewportDepths.assign(pViewportDepths,
                                               pViewportDepths + p_inherited_viewport_scissor_info->viewportDepthCount);
            }
        }
    }

    auto chained_device_group_struct = LvlFindInChain<VkDeviceGroupCommandBufferBeginInfo>(pBeginInfo->pNext);
    if (chained_device_group_struct) {
        initial_device_mask = chained_device_group_struct->deviceMask;
    } else {
        initial_device_mask = (1 << dev_data->physical_device_count) - 1;
    }
    performance_lock_acquired = dev_data->performance_lock_acquired;
}

void CMD_BUFFER_STATE::End(VkResult result) {
    // Cached validation is specific to a specific recording of a specific command buffer.
    for (auto *descriptor_set : validated_descriptor_sets) {
        descriptor_set->ClearCachedValidation(this);
    }
    validated_descriptor_sets.clear();
    if (VK_SUCCESS == result) {
        state = CB_RECORDED;
    }
}

void CMD_BUFFER_STATE::ExecuteCommands(uint32_t commandBuffersCount, const VkCommandBuffer *pCommandBuffers) {
    RecordCmd(CMD_EXECUTECOMMANDS);
    CMD_BUFFER_STATE *sub_cb_state = NULL;
    for (uint32_t i = 0; i < commandBuffersCount; i++) {
        sub_cb_state = dev_data->Get<CMD_BUFFER_STATE>(pCommandBuffers[i]);
        assert(sub_cb_state);
        if (!(sub_cb_state->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT)) {
            if (beginInfo.flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT) {
                // TODO: Because this is a state change, clearing the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT needs to be moved
                // from the validation step to the recording step
                beginInfo.flags &= ~VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
            }
        }

        // Propagate inital layout and current layout state to the primary cmd buffer
        // NOTE: The update/population of the image_layout_map is done in CoreChecks, but for other classes derived from
        // ValidationStateTracker these maps will be empty, so leaving the propagation in the the state tracker should be a no-op
        // for those other classes.
        for (const auto &sub_layout_map_entry : sub_cb_state->image_layout_map) {
            const auto image = sub_layout_map_entry.first;
            const IMAGE_STATE *image_state = dev_data->GetImageState(image);
            if (!image_state) continue;                // Can't set layouts of a dead image

            auto *cb_subres_map = GetImageSubresourceLayoutMap(*image_state);
            const auto *sub_cb_subres_map = &sub_layout_map_entry.second;
            assert(cb_subres_map && sub_cb_subres_map);  // Non const get and map traversal should never be null
            cb_subres_map->UpdateFrom(*sub_cb_subres_map);
        }

        sub_cb_state->primaryCommandBuffer = commandBuffer();
        linkedCommandBuffers.insert(sub_cb_state);
        AddChild(sub_cb_state);
        for (auto &function : sub_cb_state->queryUpdates) {
            queryUpdates.push_back(function);
        }
        for (auto &function : sub_cb_state->queue_submit_functions) {
            queue_submit_functions.push_back(function);
        }

        // State is trashed after executing secondary command buffers.
        // Importantly, this function runs after CoreChecks::PreCallValidateCmdExecuteCommands.
        trashedViewportMask = ~uint32_t(0);
        trashedScissorMask = ~uint32_t(0);
        trashedViewportCount = true;
        trashedScissorCount = true;
    }
}

void CMD_BUFFER_STATE::PushDescriptorSetState(VkPipelineBindPoint pipelineBindPoint, PIPELINE_LAYOUT_STATE *pipeline_layout,
                                              uint32_t set, uint32_t descriptorWriteCount,
                                              const VkWriteDescriptorSet *pDescriptorWrites) {
    // Short circuit invalid updates
    if (!pipeline_layout || (set >= pipeline_layout->set_layouts.size()) || !pipeline_layout->set_layouts[set] ||
        !pipeline_layout->set_layouts[set]->IsPushDescriptor()) {
        return;
    }

    // We need a descriptor set to update the bindings with, compatible with the passed layout
    const auto &dsl = pipeline_layout->set_layouts[set];
    const auto lv_bind_point = ConvertToLvlBindPoint(pipelineBindPoint);
    auto &last_bound = lastBound[lv_bind_point];
    auto &push_descriptor_set = last_bound.push_descriptor_set;
    // If we are disturbing the current push_desriptor_set clear it
    if (!push_descriptor_set || !CompatForSet(set, last_bound, pipeline_layout->compat_for_set)) {
        last_bound.UnbindAndResetPushDescriptorSet(this, new cvdescriptorset::DescriptorSet(0, nullptr, dsl, 0, dev_data));
    }

    UpdateLastBoundDescriptorSets(pipelineBindPoint, pipeline_layout, set, 1, nullptr, push_descriptor_set.get(), 0, nullptr);
    last_bound.pipeline_layout = pipeline_layout->layout();

    // Now that we have either the new or extant push_descriptor set ... do the write updates against it
    push_descriptor_set->PerformPushDescriptorsUpdate(dev_data, descriptorWriteCount, pDescriptorWrites);
}

// Generic function to handle state update for all CmdDraw* and CmdDispatch* type functions
void CMD_BUFFER_STATE::UpdateStateCmdDrawDispatchType(CMD_TYPE cmd_type, VkPipelineBindPoint bind_point) {
    UpdateDrawState(cmd_type, bind_point);
    hasDispatchCmd = true;
}

// Generic function to handle state update for all CmdDraw* type functions
void CMD_BUFFER_STATE::UpdateStateCmdDrawType(CMD_TYPE cmd_type, VkPipelineBindPoint bind_point) {
    UpdateStateCmdDrawDispatchType(cmd_type, bind_point);
    hasDrawCmd = true;

    // Update the consumed viewport/scissor count.
    uint32_t &used = usedViewportScissorCount;
    used = std::max(used, pipelineStaticViewportCount);
    used = std::max(used, pipelineStaticScissorCount);
    usedDynamicViewportCount |= !!(dynamic_status & CBSTATUS_VIEWPORT_WITH_COUNT_SET);  // !! silences MSVC warn
    usedDynamicScissorCount |= !!(dynamic_status & CBSTATUS_SCISSOR_WITH_COUNT_SET);
}

void CMD_BUFFER_STATE::UpdateDrawState(CMD_TYPE cmd_type, const VkPipelineBindPoint bind_point) {
    RecordCmd(cmd_type);

    const auto lv_bind_point = ConvertToLvlBindPoint(bind_point);
    auto &state = lastBound[lv_bind_point];
    PIPELINE_STATE *pipe = state.pipeline_state;
    if (VK_NULL_HANDLE != state.pipeline_layout) {
        for (const auto &set_binding_pair : pipe->active_slots) {
            uint32_t set_index = set_binding_pair.first;
            // Pull the set node
            cvdescriptorset::DescriptorSet *descriptor_set = state.per_set[set_index].bound_descriptor_set;

            // For the "bindless" style resource usage with many descriptors, need to optimize command <-> descriptor binding

            // TODO: If recreating the reduced_map here shows up in profilinging, need to find a way of sharing with the
            // Validate pass.  Though in the case of "many" descriptors, typically the descriptor count >> binding count
            cvdescriptorset::PrefilterBindRequestMap reduced_map(*descriptor_set, set_binding_pair.second);
            const auto &binding_req_map = reduced_map.FilteredMap(*this, *pipe);

            if (reduced_map.IsManyDescriptors()) {
                // Only update validate binding tags if we meet the "many" criteria in the Prefilter class
                descriptor_set->UpdateValidationCache(*this, *pipe, binding_req_map);
            }

            // We can skip updating the state if "nothing" has changed since the last validation.
            // See CoreChecks::ValidateCmdBufDrawState for more details.
            bool descriptor_set_changed =
                !reduced_map.IsManyDescriptors() ||
                // Update if descriptor set (or contents) has changed
                state.per_set[set_index].validated_set != descriptor_set ||
                state.per_set[set_index].validated_set_change_count != descriptor_set->GetChangeCount() ||
                (!dev_data->disabled[image_layout_validation] &&
                 state.per_set[set_index].validated_set_image_layout_change_count != image_layout_change_count);
            bool need_update = descriptor_set_changed ||
                               // Update if previous bindingReqMap doesn't include new bindingReqMap
                               !std::includes(state.per_set[set_index].validated_set_binding_req_map.begin(),
                                              state.per_set[set_index].validated_set_binding_req_map.end(), binding_req_map.begin(),
                                              binding_req_map.end());

            if (need_update) {
                // Bind this set and its active descriptor resources to the command buffer
                if (!descriptor_set_changed && reduced_map.IsManyDescriptors()) {
                    // Only record the bindings that haven't already been recorded
                    BindingReqMap delta_reqs;
                    std::set_difference(binding_req_map.begin(), binding_req_map.end(),
                                        state.per_set[set_index].validated_set_binding_req_map.begin(),
                                        state.per_set[set_index].validated_set_binding_req_map.end(),
                                        layer_data::insert_iterator<BindingReqMap>(delta_reqs, delta_reqs.begin()));
                    descriptor_set->UpdateDrawState(dev_data, this, cmd_type, pipe, delta_reqs);
                } else {
                    descriptor_set->UpdateDrawState(dev_data, this, cmd_type, pipe, binding_req_map);
                }

                state.per_set[set_index].validated_set = descriptor_set;
                state.per_set[set_index].validated_set_change_count = descriptor_set->GetChangeCount();
                state.per_set[set_index].validated_set_image_layout_change_count = image_layout_change_count;
                if (reduced_map.IsManyDescriptors()) {
                    // Check whether old == new before assigning, the equality check is much cheaper than
                    // freeing and reallocating the map.
                    if (state.per_set[set_index].validated_set_binding_req_map != set_binding_pair.second) {
                        state.per_set[set_index].validated_set_binding_req_map = set_binding_pair.second;
                    }
                } else {
                    state.per_set[set_index].validated_set_binding_req_map = BindingReqMap();
                }
            }
        }
    }
    if (pipe && !pipe->vertex_binding_descriptions_.empty()) {
        vertex_buffer_used = true;
    }
}

// Update pipeline_layout bind points applying the "Pipeline Layout Compatibility" rules.
// One of pDescriptorSets or push_descriptor_set should be nullptr, indicating whether this
// is called for CmdBindDescriptorSets or CmdPushDescriptorSet.
void CMD_BUFFER_STATE::UpdateLastBoundDescriptorSets(VkPipelineBindPoint pipeline_bind_point,
                                                     const PIPELINE_LAYOUT_STATE *pipeline_layout, uint32_t first_set,
                                                     uint32_t set_count, const VkDescriptorSet *pDescriptorSets,
                                                     cvdescriptorset::DescriptorSet *push_descriptor_set,
                                                     uint32_t dynamic_offset_count, const uint32_t *p_dynamic_offsets) {
    assert((pDescriptorSets == nullptr) ^ (push_descriptor_set == nullptr));
    // Defensive
    assert(pipeline_layout);
    if (!pipeline_layout) return;

    uint32_t required_size = first_set + set_count;
    const uint32_t last_binding_index = required_size - 1;
    assert(last_binding_index < pipeline_layout->compat_for_set.size());

    // Some useful shorthand
    const auto lv_bind_point = ConvertToLvlBindPoint(pipeline_bind_point);
    auto &last_bound = lastBound[lv_bind_point];
    auto &pipe_compat_ids = pipeline_layout->compat_for_set;
    const uint32_t current_size = static_cast<uint32_t>(last_bound.per_set.size());

    // We need this three times in this function, but nowhere else
    auto push_descriptor_cleanup = [&last_bound](const cvdescriptorset::DescriptorSet *ds) -> bool {
        if (ds && ds->IsPushDescriptor()) {
            assert(ds == last_bound.push_descriptor_set.get());
            last_bound.push_descriptor_set = nullptr;
            return true;
        }
        return false;
    };

    // Clean up the "disturbed" before and after the range to be set
    if (required_size < current_size) {
        if (last_bound.per_set[last_binding_index].compat_id_for_set != pipe_compat_ids[last_binding_index]) {
            // We're disturbing those after last, we'll shrink below, but first need to check for and cleanup the push_descriptor
            for (auto set_idx = required_size; set_idx < current_size; ++set_idx) {
                if (push_descriptor_cleanup(last_bound.per_set[set_idx].bound_descriptor_set)) break;
            }
        } else {
            // We're not disturbing past last, so leave the upper binding data alone.
            required_size = current_size;
        }
    }

    // We resize if we need more set entries or if those past "last" are disturbed
    if (required_size != current_size) {
        last_bound.per_set.resize(required_size);
    }

    // For any previously bound sets, need to set them to "invalid" if they were disturbed by this update
    for (uint32_t set_idx = 0; set_idx < first_set; ++set_idx) {
        if (last_bound.per_set[set_idx].compat_id_for_set != pipe_compat_ids[set_idx]) {
            push_descriptor_cleanup(last_bound.per_set[set_idx].bound_descriptor_set);
            last_bound.per_set[set_idx].bound_descriptor_set = nullptr;
            last_bound.per_set[set_idx].dynamicOffsets.clear();
            last_bound.per_set[set_idx].compat_id_for_set = pipe_compat_ids[set_idx];
        }
    }

    // Now update the bound sets with the input sets
    const uint32_t *input_dynamic_offsets = p_dynamic_offsets;  // "read" pointer for dynamic offset data
    for (uint32_t input_idx = 0; input_idx < set_count; input_idx++) {
        auto set_idx = input_idx + first_set;  // set_idx is index within layout, input_idx is index within input descriptor sets
        cvdescriptorset::DescriptorSet *descriptor_set =
            push_descriptor_set ? push_descriptor_set : dev_data->GetSetNode(pDescriptorSets[input_idx]);

        // Record binding (or push)
        if (descriptor_set != last_bound.push_descriptor_set.get()) {
            // Only cleanup the push descriptors if they aren't the currently used set.
            push_descriptor_cleanup(last_bound.per_set[set_idx].bound_descriptor_set);
        }
        last_bound.per_set[set_idx].bound_descriptor_set = descriptor_set;
        last_bound.per_set[set_idx].compat_id_for_set = pipe_compat_ids[set_idx];  // compat ids are canonical *per* set index

        if (descriptor_set) {
            auto set_dynamic_descriptor_count = descriptor_set->GetDynamicDescriptorCount();
            // TODO: Add logic for tracking push_descriptor offsets (here or in caller)
            if (set_dynamic_descriptor_count && input_dynamic_offsets) {
                const uint32_t *end_offset = input_dynamic_offsets + set_dynamic_descriptor_count;
                last_bound.per_set[set_idx].dynamicOffsets = std::vector<uint32_t>(input_dynamic_offsets, end_offset);
                input_dynamic_offsets = end_offset;
                assert(input_dynamic_offsets <= (p_dynamic_offsets + dynamic_offset_count));
            } else {
                last_bound.per_set[set_idx].dynamicOffsets.clear();
            }
            if (!descriptor_set->IsPushDescriptor()) {
                // Can't cache validation of push_descriptors
                validated_descriptor_sets.insert(descriptor_set);
            }
        }
    }
}

// Set image layout for given VkImageSubresourceRange struct
void CMD_BUFFER_STATE::SetImageLayout(const IMAGE_STATE &image_state, const VkImageSubresourceRange &image_subresource_range,
                                      VkImageLayout layout, VkImageLayout expected_layout) {
    auto *subresource_map = GetImageSubresourceLayoutMap(image_state);
    assert(subresource_map);  // the non-const getter must return a valid pointer
    if (subresource_map->SetSubresourceRangeLayout(*this, image_subresource_range, layout, expected_layout)) {
        image_layout_change_count++;  // Change the version of this data to force revalidation
    }
    for (const auto *alias_state : image_state.aliasing_images) {
        assert(alias_state);
        // The map state of the aliases should all be in sync, so no need to check the return value
        subresource_map = GetImageSubresourceLayoutMap(*alias_state);
        assert(subresource_map);
        subresource_map->SetSubresourceRangeLayout(*this, image_subresource_range, layout, expected_layout);
    }
}

// Set the initial image layout for all slices of an image view
void CMD_BUFFER_STATE::SetImageViewInitialLayout(const IMAGE_VIEW_STATE &view_state, VkImageLayout layout) {
    if (dev_data->disabled[image_layout_validation]) {
        return;
    }
    IMAGE_STATE *image_state = view_state.image_state.get();
    auto *subresource_map = GetImageSubresourceLayoutMap(*image_state);
    subresource_map->SetSubresourceRangeInitialLayout(*this, layout, view_state);
    for (const auto *alias_state : image_state->aliasing_images) {
        assert(alias_state);
        subresource_map = GetImageSubresourceLayoutMap(*alias_state);
        subresource_map->SetSubresourceRangeInitialLayout(*this, layout, view_state);
    }
}

// Set the initial image layout for a passed non-normalized subresource range
void CMD_BUFFER_STATE::SetImageInitialLayout(const IMAGE_STATE &image_state, const VkImageSubresourceRange &range,
                                             VkImageLayout layout) {
    auto *subresource_map = GetImageSubresourceLayoutMap(image_state);
    assert(subresource_map);
    subresource_map->SetSubresourceRangeInitialLayout(*this, image_state.NormalizeSubresourceRange(range), layout);
    for (const auto *alias_state : image_state.aliasing_images) {
        assert(alias_state);
        subresource_map = GetImageSubresourceLayoutMap(*alias_state);
        assert(subresource_map);
        subresource_map->SetSubresourceRangeInitialLayout(*this, alias_state->NormalizeSubresourceRange(range), layout);
    }
}

void CMD_BUFFER_STATE::SetImageInitialLayout(VkImage image, const VkImageSubresourceRange &range, VkImageLayout layout) {
    const IMAGE_STATE *image_state = dev_data->GetImageState(image);
    if (!image_state) return;
    SetImageInitialLayout(*image_state, range, layout);
}

void CMD_BUFFER_STATE::SetImageInitialLayout(const IMAGE_STATE &image_state, const VkImageSubresourceLayers &layers,
                                             VkImageLayout layout) {
    SetImageInitialLayout(image_state, RangeFromLayers(layers), layout);
}

// Set image layout for all slices of an image view
void CMD_BUFFER_STATE::SetImageViewLayout(const IMAGE_VIEW_STATE &view_state, VkImageLayout layout, VkImageLayout layoutStencil) {
    const IMAGE_STATE *image_state = view_state.image_state.get();

    VkImageSubresourceRange sub_range = view_state.normalized_subresource_range;

    if (sub_range.aspectMask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) && layoutStencil != kInvalidLayout) {
        sub_range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
        SetImageLayout(*image_state, sub_range, layout);
        sub_range.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
        SetImageLayout(*image_state, sub_range, layoutStencil);
    } else {
        SetImageLayout(*image_state, sub_range, layout);
    }
}

void CMD_BUFFER_STATE::RecordCmd(CMD_TYPE cmd_type) { commandCount++; }

void CMD_BUFFER_STATE::RecordStateCmd(CMD_TYPE cmd_type, CBStatusFlags state_bits) {
    RecordCmd(cmd_type);
    status |= state_bits;
    static_status &= ~state_bits;
}

void CMD_BUFFER_STATE::RecordTransferCmd(CMD_TYPE cmd_type, BINDABLE *buf1, BINDABLE *buf2) {
    RecordCmd(cmd_type);
    if (buf1) {
        AddChild(buf1);
    }
    if (buf2) {
        AddChild(buf2);
    }
}

static bool SetEventStageMask(VkEvent event, VkPipelineStageFlags2KHR stageMask, EventToStageMap *localEventToStageMap) {
    (*localEventToStageMap)[event] = stageMask;
    return false;
}

void CMD_BUFFER_STATE::RecordSetEvent(CMD_TYPE cmd_type, VkEvent event, VkPipelineStageFlags2KHR stageMask) {
    RecordCmd(cmd_type);
    if (!dev_data->disabled[command_buffer_state]) {
        auto event_state = dev_data->GetEventState(event);
        if (event_state) {
            AddChild(event_state);
        }
    }
    events.push_back(event);
    if (!waitedEvents.count(event)) {
        writeEventsBeforeWait.push_back(event);
    }
    eventUpdates.emplace_back(
        [event, stageMask](const ValidationStateTracker *device_data, bool do_validate, EventToStageMap *localEventToStageMap) {
            return SetEventStageMask(event, stageMask, localEventToStageMap);
        });
}

void CMD_BUFFER_STATE::RecordResetEvent(CMD_TYPE cmd_type, VkEvent event, VkPipelineStageFlags2KHR stageMask) {
    RecordCmd(cmd_type);
    if (!dev_data->disabled[command_buffer_state]) {
        auto event_state = dev_data->GetEventState(event);
        if (event_state) {
            AddChild(event_state);
        }
    }
    events.push_back(event);
    if (!waitedEvents.count(event)) {
        writeEventsBeforeWait.push_back(event);
    }

    eventUpdates.emplace_back([event](const ValidationStateTracker *, bool do_validate, EventToStageMap *localEventToStageMap) {
        return SetEventStageMask(event, VkPipelineStageFlags2KHR(0), localEventToStageMap);
    });
}

void CMD_BUFFER_STATE::RecordWaitEvents(CMD_TYPE cmd_type, uint32_t eventCount, const VkEvent *pEvents) {
    RecordCmd(cmd_type);
    for (uint32_t i = 0; i < eventCount; ++i) {
        if (!dev_data->disabled[command_buffer_state]) {
            auto event_state = dev_data->GetEventState(pEvents[i]);
            if (event_state) {
                AddChild(event_state);
            }
        }
        waitedEvents.insert(pEvents[i]);
        events.push_back(pEvents[i]);
    }
}

void CMD_BUFFER_STATE::RecordBarriers(uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
                                      uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers,
                                      uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) {
    if (dev_data->disabled[command_buffer_state]) return;

    for (uint32_t i = 0; i < bufferMemoryBarrierCount; i++) {
        auto buffer_state = dev_data->GetBufferState(pBufferMemoryBarriers[i].buffer);
        if (buffer_state) {
            AddChild(buffer_state);
        }
    }
    for (uint32_t i = 0; i < imageMemoryBarrierCount; i++) {
        auto image_state = dev_data->GetImageState(pImageMemoryBarriers[i].image);
        if (image_state) {
            AddChild(image_state);
        }
    }
}

void CMD_BUFFER_STATE::RecordBarriers(const VkDependencyInfoKHR &dep_info) {
    if (dev_data->disabled[command_buffer_state]) return;

    for (uint32_t i = 0; i < dep_info.bufferMemoryBarrierCount; i++) {
        auto buffer_state = dev_data->GetBufferState(dep_info.pBufferMemoryBarriers[i].buffer);
        if (buffer_state) {
            AddChild(buffer_state);
        }
    }
    for (uint32_t i = 0; i < dep_info.imageMemoryBarrierCount; i++) {
        auto image_state = dev_data->GetImageState(dep_info.pImageMemoryBarriers[i].image);
        if (image_state) {
            AddChild(image_state);
        }
    }
}

void CMD_BUFFER_STATE::RecordWriteTimestamp(CMD_TYPE cmd_type, VkPipelineStageFlags2KHR pipelineStage, VkQueryPool queryPool,
                                            uint32_t slot) {
    RecordCmd(cmd_type);
    if (dev_data->disabled[query_validation]) return;

    if (!dev_data->disabled[command_buffer_state]) {
        auto pool_state = dev_data->GetQueryPoolState(queryPool);
        AddChild(pool_state);
    }
    QueryObject query = {queryPool, slot};
    EndQuery(query);
}

void CMD_BUFFER_STATE::Submit(uint32_t perf_submit_pass) {
    VkQueryPool first_pool = VK_NULL_HANDLE;
    EventToStageMap local_event_to_stage_map;
    QueryMap local_query_to_state_map;
    for (auto &function : queryUpdates) {
        function(nullptr, /*do_validate*/ false, first_pool, perf_submit_pass, &local_query_to_state_map);
    }

    for (const auto &query_state_pair : local_query_to_state_map) {
        dev_data->queryToStateMap[query_state_pair.first] = query_state_pair.second;
    }

    for (const auto &function : eventUpdates) {
        function(nullptr, /*do_validate*/ false, &local_event_to_stage_map);
    }

    for (const auto &eventStagePair : local_event_to_stage_map) {
        dev_data->eventMap[eventStagePair.first]->stageMask = eventStagePair.second;
    }
}

void CMD_BUFFER_STATE::Retire(uint32_t perf_submit_pass) {
    // First perform decrement on general case bound objects
    for (auto event : writeEventsBeforeWait) {
        auto event_node = dev_data->eventMap.find(event);
        if (event_node != dev_data->eventMap.end()) {
            event_node->second->write_in_use--;
        }
    }
    QueryMap local_query_to_state_map;
    VkQueryPool first_pool = VK_NULL_HANDLE;
    for (auto &function : queryUpdates) {
        function(nullptr, /*do_validate*/ false, first_pool, perf_submit_pass, &local_query_to_state_map);
    }

    for (const auto &query_state_pair : local_query_to_state_map) {
        if (query_state_pair.second == QUERYSTATE_ENDED) {
            dev_data->queryToStateMap[query_state_pair.first] = QUERYSTATE_AVAILABLE;
        }
    }
}
