/* Copyright (c) 2015-2022 The Khronos Group Inc.
 * Copyright (c) 2015-2022 Valve Corporation
 * Copyright (c) 2015-2022 LunarG, Inc.
 * Copyright (C) 2015-2022 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>
 */
#pragma once
#include "base_node.h"
#include "query_state.h"
#include "command_validation.h"
#include "hash_vk_types.h"
#include "subresource_adapter.h"
#include "image_layout_map.h"
#include "pipeline_state.h"
#include "device_state.h"
#include "descriptor_sets.h"
#include "qfo_transfer.h"

struct SUBPASS_INFO;
class FRAMEBUFFER_STATE;
class RENDER_PASS_STATE;
class CoreChecks;
class ValidationStateTracker;

class EVENT_STATE : public BASE_NODE {
  public:
    int write_in_use;
    VkPipelineStageFlags2KHR stageMask = VkPipelineStageFlags2KHR(0);
    VkEventCreateFlags flags;

    EVENT_STATE(VkEvent event_, VkEventCreateFlags flags_)
        : BASE_NODE(event_, kVulkanObjectTypeEvent), write_in_use(0), flags(flags_) {}

    VkEvent event() const { return handle_.Cast<VkEvent>(); }
};

// Only CoreChecks uses this, but the state tracker stores it.
constexpr static auto kInvalidLayout = image_layout_map::kInvalidLayout;
using ImageSubresourceLayoutMap = image_layout_map::ImageSubresourceLayoutMap;
typedef layer_data::unordered_map<VkEvent, VkPipelineStageFlags2KHR> EventToStageMap;

// Track command pools and their command buffers
class COMMAND_POOL_STATE : public BASE_NODE {
  public:
    ValidationStateTracker *dev_data;
    const VkCommandPoolCreateFlags createFlags;
    const uint32_t queueFamilyIndex;
    const VkQueueFlags queue_flags;
    const bool unprotected;  // can't be used for protected memory
    // Cmd buffers allocated from this pool
    layer_data::unordered_map<VkCommandBuffer, CMD_BUFFER_STATE *> commandBuffers;

    COMMAND_POOL_STATE(ValidationStateTracker *dev, VkCommandPool cp, const VkCommandPoolCreateInfo *pCreateInfo,
                       VkQueueFlags flags);
    virtual ~COMMAND_POOL_STATE() { Destroy(); }

    VkCommandPool commandPool() const { return handle_.Cast<VkCommandPool>(); }

    void Allocate(const VkCommandBufferAllocateInfo *create_info, const VkCommandBuffer *command_buffers);
    void Free(uint32_t count, const VkCommandBuffer *command_buffers);
    void Reset();

    void Destroy() override;
};

// Autogenerated as part of the command_validation.h codegen
const char *CommandTypeString(CMD_TYPE type);

enum CB_STATE {
    CB_NEW,                 // Newly created CB w/o any cmds
    CB_RECORDING,           // BeginCB has been called on this CB
    CB_RECORDED,            // EndCB has been called on this CB
    CB_INVALID_COMPLETE,    // had a complete recording, but was since invalidated
    CB_INVALID_INCOMPLETE,  // fouled before recording was completed
};

// CB Status -- used to track status of various bindings on cmd buffer objects
typedef uint64_t CBStatusFlags;
enum CBStatusFlagBits : uint64_t {
    // clang-format off
    CBSTATUS_NONE                            = 0x00000000,   // No status is set
    CBSTATUS_LINE_WIDTH_SET                  = 0x00000001,   // Line width has been set
    CBSTATUS_DEPTH_BIAS_SET                  = 0x00000002,   // Depth bias has been set
    CBSTATUS_BLEND_CONSTANTS_SET             = 0x00000004,   // Blend constants state has been set
    CBSTATUS_DEPTH_BOUNDS_SET                = 0x00000008,   // Depth bounds state object has been set
    CBSTATUS_STENCIL_READ_MASK_SET           = 0x00000010,   // Stencil read mask has been set
    CBSTATUS_STENCIL_WRITE_MASK_SET          = 0x00000020,   // Stencil write mask has been set
    CBSTATUS_STENCIL_REFERENCE_SET           = 0x00000040,   // Stencil reference has been set
    CBSTATUS_VIEWPORT_SET                    = 0x00000080,
    CBSTATUS_SCISSOR_SET                     = 0x00000100,
    CBSTATUS_INDEX_BUFFER_BOUND              = 0x00000200,   // Index buffer has been set
    CBSTATUS_EXCLUSIVE_SCISSOR_SET           = 0x00000400,
    CBSTATUS_SHADING_RATE_PALETTE_SET        = 0x00000800,
    CBSTATUS_LINE_STIPPLE_SET                = 0x00001000,
    CBSTATUS_VIEWPORT_W_SCALING_SET          = 0x00002000,
    CBSTATUS_CULL_MODE_SET                   = 0x00004000,
    CBSTATUS_FRONT_FACE_SET                  = 0x00008000,
    CBSTATUS_PRIMITIVE_TOPOLOGY_SET          = 0x00010000,
    CBSTATUS_VIEWPORT_WITH_COUNT_SET         = 0x00020000,
    CBSTATUS_SCISSOR_WITH_COUNT_SET          = 0x00040000,
    CBSTATUS_VERTEX_INPUT_BINDING_STRIDE_SET = 0x00080000,
    CBSTATUS_DEPTH_TEST_ENABLE_SET           = 0x00100000,
    CBSTATUS_DEPTH_WRITE_ENABLE_SET          = 0x00200000,
    CBSTATUS_DEPTH_COMPARE_OP_SET            = 0x00400000,
    CBSTATUS_DEPTH_BOUNDS_TEST_ENABLE_SET    = 0x00800000,
    CBSTATUS_STENCIL_TEST_ENABLE_SET         = 0x01000000,
    CBSTATUS_STENCIL_OP_SET                  = 0x02000000,
    CBSTATUS_DISCARD_RECTANGLE_SET           = 0x04000000,
    CBSTATUS_SAMPLE_LOCATIONS_SET            = 0x08000000,
    CBSTATUS_COARSE_SAMPLE_ORDER_SET         = 0x10000000,
    CBSTATUS_PATCH_CONTROL_POINTS_SET        = 0x20000000,
    CBSTATUS_RASTERIZER_DISCARD_ENABLE_SET   = 0x40000000,
    CBSTATUS_DEPTH_BIAS_ENABLE_SET           = 0x80000000,
    CBSTATUS_LOGIC_OP_SET                    = 0x100000000,
    CBSTATUS_PRIMITIVE_RESTART_ENABLE_SET    = 0x200000000,
    CBSTATUS_VERTEX_INPUT_SET                = 0x400000000,
    CBSTATUS_COLOR_WRITE_ENABLE_SET          = 0x800000000,
    CBSTATUS_ALL_STATE_SET                   = 0xFFFFFFDFF,   // All state set (intentionally exclude index buffer)
    // clang-format on
};

VkDynamicState ConvertToDynamicState(CBStatusFlagBits flag);
CBStatusFlagBits ConvertToCBStatusFlagBits(VkDynamicState state);
std::string DynamicStateString(CBStatusFlags input_value);

struct BufferBinding {
    std::shared_ptr<BUFFER_STATE> buffer_state;
    VkDeviceSize size;
    VkDeviceSize offset;
    VkDeviceSize stride;

    BufferBinding() : buffer_state(), size(0), offset(0), stride(0) {}
    virtual ~BufferBinding() {}

    virtual void reset() { *this = BufferBinding(); }
};

struct IndexBufferBinding : BufferBinding {
    VkIndexType index_type;

    IndexBufferBinding() : BufferBinding(), index_type(static_cast<VkIndexType>(0)) {}
    virtual ~IndexBufferBinding() {}

    virtual void reset() override { *this = IndexBufferBinding(); }
};

struct CBVertexBufferBindingInfo {
    std::vector<BufferBinding> vertex_buffer_bindings;
};

typedef layer_data::unordered_map<const IMAGE_STATE *, std::shared_ptr<ImageSubresourceLayoutMap>> CommandBufferImageLayoutMap;

typedef layer_data::unordered_map<const GlobalImageLayoutRangeMap *, std::shared_ptr<ImageSubresourceLayoutMap>>
    CommandBufferAliasedLayoutMap;

class CMD_BUFFER_STATE : public REFCOUNTED_NODE {
  public:
    VkCommandBufferAllocateInfo createInfo = {};
    VkCommandBufferBeginInfo beginInfo;
    VkCommandBufferInheritanceInfo inheritanceInfo;
    // since command buffers can only be destroyed by their command pool, this does not need to be a shared_ptr
    const COMMAND_POOL_STATE *command_pool;
    ValidationStateTracker *dev_data;
    bool hasDrawCmd;
    bool hasTraceRaysCmd;
    bool hasBuildAccelerationStructureCmd;
    bool hasDispatchCmd;
    bool unprotected;  // can't be used for protected memory
    bool hasRenderPassInstance;
    bool suspendsRenderPassInstance;
    bool resumesRenderPassInstance;

    CB_STATE state;         // Track cmd buffer update state
    uint64_t commandCount;  // Number of commands recorded. Currently only used with VK_KHR_performance_query
    uint64_t submitCount;   // Number of times CB has been submitted
    typedef uint64_t ImageLayoutUpdateCount;
    ImageLayoutUpdateCount image_layout_change_count;  // The sequence number for changes to image layout (for cached validation)
    CBStatusFlags status;                              // Track status of various bindings on cmd buffer
    CBStatusFlags static_status;                       // All state bits provided by current graphics pipeline
                                                       // rather than dynamic state
    CBStatusFlags dynamic_status;                      // dynamic state set up in pipeline
    std::string begin_rendering_func_name;
    // Currently storing "lastBound" objects on per-CB basis
    //  long-term may want to create caches of "lastBound" states and could have
    //  each individual CMD_NODE referencing its own "lastBound" state
    // Store last bound state for Gfx & Compute pipeline bind points
    std::array<LAST_BOUND_STATE, BindPoint_Count> lastBound;  // index is LvlBindPoint.

    // Use the casting boilerplate from BASE_NODE to implement the derived shared_from_this
    std::shared_ptr<const CMD_BUFFER_STATE> shared_from_this() const { return SharedFromThisImpl(this); }
    std::shared_ptr<CMD_BUFFER_STATE> shared_from_this() { return SharedFromThisImpl(this); }

    struct CmdDrawDispatchInfo {
        CMD_TYPE cmd_type;
        std::vector<std::pair<const uint32_t, DescriptorRequirement>> binding_infos;
        VkFramebuffer framebuffer;
        std::shared_ptr<std::vector<SUBPASS_INFO>> subpasses;
        std::shared_ptr<std::vector<IMAGE_VIEW_STATE *>> attachments;
    };
    layer_data::unordered_map<VkDescriptorSet, std::vector<CmdDrawDispatchInfo>> validate_descriptorsets_in_queuesubmit;

    // If VK_NV_inherited_viewport_scissor is enabled and VkCommandBufferInheritanceViewportScissorInfoNV::viewportScissor2D is
    // true, then is the nonempty list of viewports passed in pViewportDepths. Otherwise, this is empty.
    std::vector<VkViewport> inheritedViewportDepths;

    // For each draw command D recorded to this command buffer, let
    //  * g_D be the graphics pipeline used
    //  * v_G be the viewportCount of g_D (0 if g_D disables rasterization or enables VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT)
    //  * s_G be the scissorCount  of g_D (0 if g_D disables rasterization or enables VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT)
    // Then this value is max(0, max(v_G for all D in cb), max(s_G for all D in cb))
    uint32_t usedViewportScissorCount;
    uint32_t pipelineStaticViewportCount;  // v_G for currently-bound graphics pipeline.
    uint32_t pipelineStaticScissorCount;   // s_G for currently-bound graphics pipeline.

    uint32_t viewportMask;
    uint32_t viewportWithCountMask;
    uint32_t viewportWithCountCount;
    uint32_t scissorMask;
    uint32_t scissorWithCountMask;
    uint32_t scissorWithCountCount;

    // Dynamic viewports set in this command buffer; if bit j of viewportMask is set then dynamicViewports[j] is valid, but the
    // converse need not be true.
    std::vector<VkViewport> dynamicViewports;

    // Bits set when binding graphics pipeline defining corresponding static state, or executing any secondary command buffer.
    // Bits unset by calling a corresponding vkCmdSet[State] cmd.
    uint32_t trashedViewportMask;
    uint32_t trashedScissorMask;
    bool trashedViewportCount;
    bool trashedScissorCount;

    // True iff any draw command recorded to this command buffer consumes dynamic viewport/scissor with count state.
    bool usedDynamicViewportCount;
    bool usedDynamicScissorCount;

    uint32_t initial_device_mask;
    VkPrimitiveTopology primitiveTopology;

    safe_VkRenderPassBeginInfo activeRenderPassBeginInfo;
    std::shared_ptr<RENDER_PASS_STATE> activeRenderPass;
    std::shared_ptr<std::vector<SUBPASS_INFO>> active_subpasses;
    std::shared_ptr<std::vector<IMAGE_VIEW_STATE *>> active_attachments;
    std::set<std::shared_ptr<IMAGE_VIEW_STATE>> attachments_view_states;

    VkSubpassContents activeSubpassContents;
    uint32_t active_render_pass_device_mask;
    uint32_t activeSubpass;
    std::shared_ptr<FRAMEBUFFER_STATE> activeFramebuffer;
    layer_data::unordered_set<std::shared_ptr<FRAMEBUFFER_STATE>> framebuffers;
    // Unified data structs to track objects bound to this command buffer as well as object
    //  dependencies that have been broken : either destroyed objects, or updated descriptor sets
    layer_data::unordered_set<std::shared_ptr<BASE_NODE>> object_bindings;
    layer_data::unordered_map<VulkanTypedHandle, LogObjectList> broken_bindings;

    QFOTransferBarrierSets<QFOBufferTransferBarrier> qfo_transfer_buffer_barriers;
    QFOTransferBarrierSets<QFOImageTransferBarrier> qfo_transfer_image_barriers;

    layer_data::unordered_set<VkEvent> waitedEvents;
    std::vector<VkEvent> writeEventsBeforeWait;
    std::vector<VkEvent> events;
    layer_data::unordered_set<QueryObject> activeQueries;
    layer_data::unordered_set<QueryObject> startedQueries;
    layer_data::unordered_set<QueryObject> resetQueries;
    layer_data::unordered_set<QueryObject> updatedQueries;
    CommandBufferImageLayoutMap image_layout_map;
    CommandBufferAliasedLayoutMap aliased_image_layout_map;  // storage for potentially aliased images

    CBVertexBufferBindingInfo current_vertex_buffer_binding_info;
    bool vertex_buffer_used;  // Track for perf warning to make sure any bound vtx buffer used
    VkCommandBuffer primaryCommandBuffer;
    // If primary, the secondary command buffers we will call.
    // If secondary, the primary command buffers we will be called by.
    layer_data::unordered_set<CMD_BUFFER_STATE *> linkedCommandBuffers;
    // Validation functions run at primary CB queue submit time
    using QueueCallback = std::function<bool(const ValidationStateTracker &device_data, const class QUEUE_STATE &queue_state,
                                             const CMD_BUFFER_STATE &cb_state)>;
    std::vector<QueueCallback> queue_submit_functions;
    // Used by some layers to defer actions until vkCmdEndRenderPass time.
    // Layers using this are responsible for inserting the callbacks into queue_submit_functions.
    std::vector<QueueCallback> queue_submit_functions_after_render_pass;
    // Validation functions run when secondary CB is executed in primary
    std::vector<std::function<bool(const CMD_BUFFER_STATE &secondary, const CMD_BUFFER_STATE *primary, const FRAMEBUFFER_STATE *)>>
        cmd_execute_commands_functions;
    std::vector<std::function<bool(CMD_BUFFER_STATE &cb, bool do_validate, EventToStageMap *localEventToStageMap)>> eventUpdates;
    std::vector<std::function<bool(const ValidationStateTracker *device_data, bool do_validate, VkQueryPool &firstPerfQueryPool,
                                   uint32_t perfQueryPass, QueryMap *localQueryToStateMap)>>
        queryUpdates;
    layer_data::unordered_set<const cvdescriptorset::DescriptorSet *> validated_descriptor_sets;
    layer_data::unordered_map<const cvdescriptorset::DescriptorSet *, cvdescriptorset::DescriptorSet::CachedValidation>
        descriptorset_cache;
    // Contents valid only after an index buffer is bound (CBSTATUS_INDEX_BUFFER_BOUND set)
    IndexBufferBinding index_buffer_binding;
    bool performance_lock_acquired = false;
    bool performance_lock_released = false;

    // Cache of current insert label...
    LoggingLabel debug_label;

    std::vector<uint8_t> push_constant_data;
    PushConstantRangesId push_constant_data_ranges;

    std::map<VkShaderStageFlagBits, std::vector<uint8_t>>
        push_constant_data_update;  // vector's value is enum PushConstantByteState.
    VkPipelineLayout push_constant_pipeline_layout_set;

    // Used for Best Practices tracking
    uint32_t small_indexed_draw_call_count;

    bool transform_feedback_active{false};
    bool conditional_rendering_active{false};
    bool conditional_rendering_inside_render_pass{false};
    uint32_t conditional_rendering_subpass{0};
    uint32_t dynamicColorWriteEnableAttachmentCount{0};
    mutable ReadWriteLock lock;
    ReadLockGuard ReadLock() const { return ReadLockGuard(lock); }
    WriteLockGuard WriteLock() { return WriteLockGuard(lock); }

    CMD_BUFFER_STATE(ValidationStateTracker *, VkCommandBuffer cb, const VkCommandBufferAllocateInfo *pCreateInfo,
                     const COMMAND_POOL_STATE *cmd_pool);

    virtual ~CMD_BUFFER_STATE() { Destroy(); }

    void Destroy() override;

    VkCommandBuffer commandBuffer() const { return handle_.Cast<VkCommandBuffer>(); }

    IMAGE_VIEW_STATE *GetActiveAttachmentImageViewState(uint32_t index);
    const IMAGE_VIEW_STATE *GetActiveAttachmentImageViewState(uint32_t index) const;

    void AddChild(std::shared_ptr<BASE_NODE> &base_node);
    template <typename StateObject>
    void AddChild(std::shared_ptr<StateObject> &child_node) {
        auto base = std::static_pointer_cast<BASE_NODE>(child_node);
        AddChild(base);
    }

    void RemoveChild(std::shared_ptr<BASE_NODE> &base_node);
    template <typename StateObject>
    void RemoveChild(std::shared_ptr<StateObject> &child_node) {
        auto base = std::static_pointer_cast<BASE_NODE>(child_node);
        RemoveChild(base);
    }

    virtual void Reset();

    void IncrementResources();

    void ResetPushConstantDataIfIncompatible(const PIPELINE_LAYOUT_STATE *pipeline_layout_state);

    const ImageSubresourceLayoutMap *GetImageSubresourceLayoutMap(const IMAGE_STATE &image_state) const;
    ImageSubresourceLayoutMap *GetImageSubresourceLayoutMap(const IMAGE_STATE &image_state);
    const CommandBufferImageLayoutMap& GetImageSubresourceLayoutMap() const;

    const QFOTransferBarrierSets<QFOImageTransferBarrier> &GetQFOBarrierSets(const QFOImageTransferBarrier &type_tag) const {
        return qfo_transfer_image_barriers;
    }

    const QFOTransferBarrierSets<QFOBufferTransferBarrier> &GetQFOBarrierSets(const QFOBufferTransferBarrier &type_tag) const {
        return qfo_transfer_buffer_barriers;
    }

    QFOTransferBarrierSets<QFOImageTransferBarrier> &GetQFOBarrierSets(const QFOImageTransferBarrier &type_tag) {
        return qfo_transfer_image_barriers;
    }

    QFOTransferBarrierSets<QFOBufferTransferBarrier> &GetQFOBarrierSets(const QFOBufferTransferBarrier &type_tag) {
        return qfo_transfer_buffer_barriers;
    }

    PIPELINE_STATE *GetCurrentPipeline(VkPipelineBindPoint pipelineBindPoint) const {
        const auto lv_bind_point = ConvertToLvlBindPoint(pipelineBindPoint);
        return lastBound[lv_bind_point].pipeline_state;
    }

    void GetCurrentPipelineAndDesriptorSets(VkPipelineBindPoint pipelineBindPoint, const PIPELINE_STATE **rtn_pipe,
                                            const std::vector<LAST_BOUND_STATE::PER_SET> **rtn_sets) const {
        const auto lv_bind_point = ConvertToLvlBindPoint(pipelineBindPoint);
        const auto &last_bound_it = lastBound[lv_bind_point];
        if (!last_bound_it.IsUsing()) {
            return;
        }
        *rtn_pipe = last_bound_it.pipeline_state;
        *rtn_sets = &(last_bound_it.per_set);
    }

    VkQueueFlags GetQueueFlags() const {
	    return command_pool->queue_flags;
    }

    template <typename Barrier>
    inline bool IsReleaseOp(const Barrier &barrier) const {
        return (IsTransferOp(barrier)) && (command_pool->queueFamilyIndex == barrier.srcQueueFamilyIndex);
    }
    template <typename Barrier>
    inline bool IsAcquireOp(const Barrier &barrier) const {
        return (IsTransferOp(barrier)) && (command_pool->queueFamilyIndex == barrier.dstQueueFamilyIndex);
    }

    void Begin(const VkCommandBufferBeginInfo *pBeginInfo);
    void End(VkResult result);

    void BeginQuery(const QueryObject &query_obj);
    void EndQuery(const QueryObject &query_obj);
    void EndQueries(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount);
    void ResetQueryPool(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount);

    void BeginRenderPass(CMD_TYPE cmd_type, const VkRenderPassBeginInfo *pRenderPassBegin, VkSubpassContents contents);
    void NextSubpass(CMD_TYPE cmd_type, VkSubpassContents contents);
    void EndRenderPass(CMD_TYPE cmd_type);

    void BeginRendering(CMD_TYPE cmd_type, const VkRenderingInfo *pRenderingInfo);

    void ExecuteCommands(uint32_t commandBuffersCount, const VkCommandBuffer *pCommandBuffers);

    void UpdateLastBoundDescriptorSets(VkPipelineBindPoint pipeline_bind_point, const PIPELINE_LAYOUT_STATE *pipeline_layout,
                                       uint32_t first_set, uint32_t set_count, const VkDescriptorSet *pDescriptorSets,
                                       std::shared_ptr<cvdescriptorset::DescriptorSet> &push_descriptor_set,
                                       uint32_t dynamic_offset_count, const uint32_t *p_dynamic_offsets);

    void PushDescriptorSetState(VkPipelineBindPoint pipelineBindPoint, PIPELINE_LAYOUT_STATE *pipeline_layout, uint32_t set,
                                uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites);

    void UpdateStateCmdDrawDispatchType(CMD_TYPE cmd_type, VkPipelineBindPoint bind_point);
    void UpdateStateCmdDrawType(CMD_TYPE cmd_type, VkPipelineBindPoint bind_point);
    void UpdateDrawState(CMD_TYPE cmd_type, const VkPipelineBindPoint bind_point);

    virtual void RecordCmd(CMD_TYPE cmd_type);
    void RecordStateCmd(CMD_TYPE cmd_type, CBStatusFlags state_bits);
    void RecordColorWriteEnableStateCmd(CMD_TYPE cmd_type, CBStatusFlags state_bits, uint32_t attachment_count);
    void RecordTransferCmd(CMD_TYPE cmd_type, std::shared_ptr<BINDABLE> &&buf1, std::shared_ptr<BINDABLE> &&buf2 = nullptr);
    void RecordSetEvent(CMD_TYPE cmd_type, VkEvent event, VkPipelineStageFlags2KHR stageMask);
    void RecordResetEvent(CMD_TYPE cmd_type, VkEvent event, VkPipelineStageFlags2KHR stageMask);
    virtual void RecordWaitEvents(CMD_TYPE cmd_type, uint32_t eventCount, const VkEvent *pEvents,
                                  VkPipelineStageFlags2KHR src_stage_mask);
    void RecordWriteTimestamp(CMD_TYPE cmd_type, VkPipelineStageFlags2KHR pipelineStage, VkQueryPool queryPool, uint32_t slot);

    void RecordBarriers(uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, uint32_t bufferMemoryBarrierCount,
                        const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
                        const VkImageMemoryBarrier *pImageMemoryBarriers);
    void RecordBarriers(const VkDependencyInfoKHR &dep_info);

    void SetImageViewLayout(const IMAGE_VIEW_STATE &view_state, VkImageLayout layout, VkImageLayout layoutStencil);
    void SetImageViewInitialLayout(const IMAGE_VIEW_STATE &view_state, VkImageLayout layout);

    void SetImageLayout(const IMAGE_STATE &image_state, const VkImageSubresourceRange &image_subresource_range,
                        VkImageLayout layout, VkImageLayout expected_layout = kInvalidLayout);
    void SetImageLayout(const IMAGE_STATE &image_state, const VkImageSubresourceLayers &image_subresource_layers,
                        VkImageLayout layout);
    void SetImageInitialLayout(VkImage image, const VkImageSubresourceRange &range, VkImageLayout layout);
    void SetImageInitialLayout(const IMAGE_STATE &image_state, const VkImageSubresourceRange &range, VkImageLayout layout);
    void SetImageInitialLayout(const IMAGE_STATE &image_state, const VkImageSubresourceLayers &layers, VkImageLayout layout);

    void Submit(uint32_t perf_submit_pass);
    void Retire(uint32_t perf_submit_pass, const std::function<bool(const QueryObject &)> &is_query_updated_after);

    uint32_t GetDynamicColorAttachmentCount() {
        if (activeRenderPass) {
            if (activeRenderPass->use_dynamic_rendering_inherited) {
                return activeRenderPass->inheritance_rendering_info.colorAttachmentCount;
            }
            if (activeRenderPass->use_dynamic_rendering) {
                return activeRenderPass->dynamic_rendering_begin_rendering_info.colorAttachmentCount;
            }
        }
        return 0;
    }
    uint32_t GetDynamicColorAttachmentImageIndex(uint32_t index) { return index; }
    uint32_t GetDynamicColorResolveAttachmentImageIndex(uint32_t index) { return index + GetDynamicColorAttachmentCount(); }
    uint32_t GetDynamicDepthAttachmentImageIndex() { return 2 * GetDynamicColorAttachmentCount(); }
    uint32_t GetDynamicDepthResolveAttachmentImageIndex() { return 2 * GetDynamicColorAttachmentCount() + 1; }
    uint32_t GetDynamicStencilAttachmentImageIndex() { return 2 * GetDynamicColorAttachmentCount() + 2; }
    uint32_t GetDynamicStencilResolveAttachmentImageIndex() { return 2 * GetDynamicColorAttachmentCount() + 3; }

  protected:
    void NotifyInvalidate(const BASE_NODE::NodeList &invalid_nodes, bool unlink) override;
    void UpdateAttachmentsView(const VkRenderPassBeginInfo *pRenderPassBegin);
    void UnbindResources();
};

// specializations for barriers that cannot do queue family ownership transfers
template <>
inline bool CMD_BUFFER_STATE::IsReleaseOp(const VkMemoryBarrier &barrier) const {
    return false;
}
template <>
inline bool CMD_BUFFER_STATE::IsReleaseOp(const VkMemoryBarrier2KHR &barrier) const {
    return false;
}
template <>
inline bool CMD_BUFFER_STATE::IsReleaseOp(const VkSubpassDependency2 &barrier) const {
    return false;
}
template <>
inline bool CMD_BUFFER_STATE::IsAcquireOp(const VkMemoryBarrier &barrier) const {
    return false;
}
template <>
inline bool CMD_BUFFER_STATE::IsAcquireOp(const VkMemoryBarrier2KHR &barrier) const {
    return false;
}
template <>
inline bool CMD_BUFFER_STATE::IsAcquireOp(const VkSubpassDependency2 &barrier) const {
    return false;
}
