/* 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"

COMMAND_POOL_STATE::COMMAND_POOL_STATE(ValidationStateTracker *dev, VkCommandPool cp, const VkCommandPoolCreateInfo *pCreateInfo,
                                       VkQueueFlags flags)
    : BASE_NODE(cp, kVulkanObjectTypeCommandPool),
      dev_data(dev),
      createFlags(pCreateInfo->flags),
      queueFamilyIndex(pCreateInfo->queueFamilyIndex),
      queue_flags(flags),
      unprotected((pCreateInfo->flags & VK_COMMAND_POOL_CREATE_PROTECTED_BIT) == 0) {}

void COMMAND_POOL_STATE::Allocate(const VkCommandBufferAllocateInfo *create_info, const VkCommandBuffer *command_buffers) {
    for (uint32_t i = 0; i < create_info->commandBufferCount; i++) {
        auto new_cb = dev_data->CreateCmdBufferState(command_buffers[i], create_info, this);
        commandBuffers.emplace(command_buffers[i], new_cb.get());
        dev_data->Add(std::move(new_cb));
    }
}

void COMMAND_POOL_STATE::Free(uint32_t count, const VkCommandBuffer *command_buffers) {
    for (uint32_t i = 0; i < count; i++) {
        auto iter = commandBuffers.find(command_buffers[i]);
        if (iter != commandBuffers.end()) {
            dev_data->Destroy<CMD_BUFFER_STATE>(iter->first);
            commandBuffers.erase(iter);
        }
    }
}

void COMMAND_POOL_STATE::Reset() {
    for (auto &entry : commandBuffers) {
        entry.second->Reset();
    }
}

void COMMAND_POOL_STATE::Destroy() {
    for (auto &entry : commandBuffers) {
        dev_data->Destroy<CMD_BUFFER_STATE>(entry.first);
    }
    commandBuffers.clear();
    BASE_NODE::Destroy();
}

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 *dev, VkCommandBuffer cb, const VkCommandBufferAllocateInfo *pCreateInfo,
                                   const COMMAND_POOL_STATE *pool)
    : REFCOUNTED_NODE(cb, kVulkanObjectTypeCommandBuffer),
      createInfo(*pCreateInfo),
      command_pool(pool),
      dev_data(dev),
      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) {
    assert(child_node);
    if (child_node->AddParent(this)) {
        object_bindings.insert(child_node);
    }
}

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

// 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) {
        obj->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 (auto *base_obj : object_bindings) {
        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 BASE_NODE::NodeList &invalid_nodes, bool unlink) {
    if (state == CB_RECORDING) {
        state = CB_INVALID_INCOMPLETE;
    } else if (state == CB_RECORDED) {
        state = CB_INVALID_COMPLETE;
    }
    assert(!invalid_nodes.empty());
    LogObjectList log_list;
    for (auto *obj : invalid_nodes) {
        log_list.object_list.emplace_back(obj->Handle());
    }
    broken_bindings.emplace(invalid_nodes[0]->Handle(), log_list);

    if (unlink) {
        for (auto *obj : invalid_nodes) {
            object_bindings.erase(obj);
            switch (obj->Type()) {
                case kVulkanObjectTypeCommandBuffer:
                    linkedCommandBuffers.erase(static_cast<CMD_BUFFER_STATE *>(obj));
                    break;
                case kVulkanObjectTypeImage:
                    image_layout_map.erase(static_cast<IMAGE_STATE *>(obj));
                    break;
                default:
                    break;
            }
        }
    }
    BASE_NODE::NotifyInvalidate(invalid_nodes, unlink);
}

const CommandBufferImageLayoutMap& CMD_BUFFER_STATE::GetImageSubresourceLayoutMap() const { return image_layout_map; }

// The const variant only need the image as it is the key for the map
const ImageSubresourceLayoutMap *CMD_BUFFER_STATE::GetImageSubresourceLayoutMap(const IMAGE_STATE &image_state) const {
    auto it = image_layout_map.find(&image_state);
    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];
    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.
    descriptorset_cache.clear();
    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_state = sub_layout_map_entry.first;

            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->Get<EVENT_STATE>(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_state = dev_data->Get<EVENT_STATE>(event);
        if (event_state) {
            event_state->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;
        }
    }
}
