1 /* Copyright (c) 2015-2021 The Khronos Group Inc.
2  * Copyright (c) 2015-2021 Valve Corporation
3  * Copyright (c) 2015-2021 LunarG, Inc.
4  * Copyright (C) 2015-2021 Google Inc.
5  * Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * Author: Courtney Goeltzenleuchter <courtneygo@google.com>
20  * Author: Tobin Ehlis <tobine@google.com>
21  * Author: Chris Forbes <chrisf@ijw.co.nz>
22  * Author: Mark Lobodzinski <mark@lunarg.com>
23  * Author: Dave Houlton <daveh@lunarg.com>
24  * Author: John Zulauf <jzulauf@lunarg.com>
25  * Author: Tobias Hector <tobias.hector@amd.com>
26  */
27 #pragma once
28 #include "base_node.h"
29 #include "query_state.h"
30 #include "command_validation.h"
31 #include "hash_vk_types.h"
32 #include "subresource_adapter.h"
33 #include "image_layout_map.h"
34 #include "pipeline_state.h"
35 #include "device_state.h"
36 #include "descriptor_sets.h"
37 #include "qfo_transfer.h"
38 
39 struct SUBPASS_INFO;
40 class FRAMEBUFFER_STATE;
41 class RENDER_PASS_STATE;
42 class CoreChecks;
43 class ValidationStateTracker;
44 
45 class EVENT_STATE : public BASE_NODE {
46   public:
47     int write_in_use;
48     VkPipelineStageFlags2KHR stageMask = VkPipelineStageFlags2KHR(0);
49     VkEventCreateFlags flags;
50 
EVENT_STATE(VkEvent event_,VkEventCreateFlags flags_)51     EVENT_STATE(VkEvent event_, VkEventCreateFlags flags_)
52         : BASE_NODE(event_, kVulkanObjectTypeEvent), write_in_use(0), flags(flags_) {}
53 
event()54     VkEvent event() const { return handle_.Cast<VkEvent>(); }
55 };
56 
57 // Only CoreChecks uses this, but the state tracker stores it.
58 constexpr static auto kInvalidLayout = image_layout_map::kInvalidLayout;
59 using ImageSubresourceLayoutMap = image_layout_map::ImageSubresourceLayoutMap;
60 typedef layer_data::unordered_map<VkEvent, VkPipelineStageFlags2KHR> EventToStageMap;
61 
62 // Track command pools and their command buffers
63 class COMMAND_POOL_STATE : public BASE_NODE {
64   public:
65     ValidationStateTracker *dev_data;
66     const VkCommandPoolCreateFlags createFlags;
67     const uint32_t queueFamilyIndex;
68     const VkQueueFlags queue_flags;
69     const bool unprotected;  // can't be used for protected memory
70     // Cmd buffers allocated from this pool
71     layer_data::unordered_map<VkCommandBuffer, CMD_BUFFER_STATE *> commandBuffers;
72 
73     COMMAND_POOL_STATE(ValidationStateTracker *dev, VkCommandPool cp, const VkCommandPoolCreateInfo *pCreateInfo,
74                        VkQueueFlags flags);
~COMMAND_POOL_STATE()75     virtual ~COMMAND_POOL_STATE() { Destroy(); }
76 
commandPool()77     VkCommandPool commandPool() const { return handle_.Cast<VkCommandPool>(); }
78 
79     void Allocate(const VkCommandBufferAllocateInfo *create_info, const VkCommandBuffer *command_buffers);
80     void Free(uint32_t count, const VkCommandBuffer *command_buffers);
81     void Reset();
82 
83     void Destroy() override;
84 };
85 
86 // Autogenerated as part of the command_validation.h codegen
87 const char *CommandTypeString(CMD_TYPE type);
88 
89 enum CB_STATE {
90     CB_NEW,                 // Newly created CB w/o any cmds
91     CB_RECORDING,           // BeginCB has been called on this CB
92     CB_RECORDED,            // EndCB has been called on this CB
93     CB_INVALID_COMPLETE,    // had a complete recording, but was since invalidated
94     CB_INVALID_INCOMPLETE,  // fouled before recording was completed
95 };
96 
97 // CB Status -- used to track status of various bindings on cmd buffer objects
98 typedef uint64_t CBStatusFlags;
99 enum CBStatusFlagBits : uint64_t {
100     // clang-format off
101     CBSTATUS_NONE                            = 0x00000000,   // No status is set
102     CBSTATUS_LINE_WIDTH_SET                  = 0x00000001,   // Line width has been set
103     CBSTATUS_DEPTH_BIAS_SET                  = 0x00000002,   // Depth bias has been set
104     CBSTATUS_BLEND_CONSTANTS_SET             = 0x00000004,   // Blend constants state has been set
105     CBSTATUS_DEPTH_BOUNDS_SET                = 0x00000008,   // Depth bounds state object has been set
106     CBSTATUS_STENCIL_READ_MASK_SET           = 0x00000010,   // Stencil read mask has been set
107     CBSTATUS_STENCIL_WRITE_MASK_SET          = 0x00000020,   // Stencil write mask has been set
108     CBSTATUS_STENCIL_REFERENCE_SET           = 0x00000040,   // Stencil reference has been set
109     CBSTATUS_VIEWPORT_SET                    = 0x00000080,
110     CBSTATUS_SCISSOR_SET                     = 0x00000100,
111     CBSTATUS_INDEX_BUFFER_BOUND              = 0x00000200,   // Index buffer has been set
112     CBSTATUS_EXCLUSIVE_SCISSOR_SET           = 0x00000400,
113     CBSTATUS_SHADING_RATE_PALETTE_SET        = 0x00000800,
114     CBSTATUS_LINE_STIPPLE_SET                = 0x00001000,
115     CBSTATUS_VIEWPORT_W_SCALING_SET          = 0x00002000,
116     CBSTATUS_CULL_MODE_SET                   = 0x00004000,
117     CBSTATUS_FRONT_FACE_SET                  = 0x00008000,
118     CBSTATUS_PRIMITIVE_TOPOLOGY_SET          = 0x00010000,
119     CBSTATUS_VIEWPORT_WITH_COUNT_SET         = 0x00020000,
120     CBSTATUS_SCISSOR_WITH_COUNT_SET          = 0x00040000,
121     CBSTATUS_VERTEX_INPUT_BINDING_STRIDE_SET = 0x00080000,
122     CBSTATUS_DEPTH_TEST_ENABLE_SET           = 0x00100000,
123     CBSTATUS_DEPTH_WRITE_ENABLE_SET          = 0x00200000,
124     CBSTATUS_DEPTH_COMPARE_OP_SET            = 0x00400000,
125     CBSTATUS_DEPTH_BOUNDS_TEST_ENABLE_SET    = 0x00800000,
126     CBSTATUS_STENCIL_TEST_ENABLE_SET         = 0x01000000,
127     CBSTATUS_STENCIL_OP_SET                  = 0x02000000,
128     CBSTATUS_DISCARD_RECTANGLE_SET           = 0x04000000,
129     CBSTATUS_SAMPLE_LOCATIONS_SET            = 0x08000000,
130     CBSTATUS_COARSE_SAMPLE_ORDER_SET         = 0x10000000,
131     CBSTATUS_PATCH_CONTROL_POINTS_SET        = 0x20000000,
132     CBSTATUS_RASTERIZER_DISCARD_ENABLE_SET   = 0x40000000,
133     CBSTATUS_DEPTH_BIAS_ENABLE_SET           = 0x80000000,
134     CBSTATUS_LOGIC_OP_SET                    = 0x100000000,
135     CBSTATUS_PRIMITIVE_RESTART_ENABLE_SET    = 0x200000000,
136     CBSTATUS_VERTEX_INPUT_SET                = 0x400000000,
137     CBSTATUS_ALL_STATE_SET                   = 0x7FFFFFDFF,   // All state set (intentionally exclude index buffer)
138     // clang-format on
139 };
140 
141 VkDynamicState ConvertToDynamicState(CBStatusFlagBits flag);
142 CBStatusFlagBits ConvertToCBStatusFlagBits(VkDynamicState state);
143 std::string DynamicStateString(CBStatusFlags input_value);
144 
145 struct BufferBinding {
146     std::shared_ptr<BUFFER_STATE> buffer_state;
147     VkDeviceSize size;
148     VkDeviceSize offset;
149     VkDeviceSize stride;
150 
BufferBindingBufferBinding151     BufferBinding() : buffer_state(), size(0), offset(0), stride(0) {}
~BufferBindingBufferBinding152     virtual ~BufferBinding() {}
153 
resetBufferBinding154     virtual void reset() { *this = BufferBinding(); }
155 };
156 
157 struct IndexBufferBinding : BufferBinding {
158     VkIndexType index_type;
159 
IndexBufferBindingIndexBufferBinding160     IndexBufferBinding() : BufferBinding(), index_type(static_cast<VkIndexType>(0)) {}
~IndexBufferBindingIndexBufferBinding161     virtual ~IndexBufferBinding() {}
162 
resetIndexBufferBinding163     virtual void reset() override { *this = IndexBufferBinding(); }
164 };
165 
166 struct CBVertexBufferBindingInfo {
167     std::vector<BufferBinding> vertex_buffer_bindings;
168 };
169 
170 typedef layer_data::unordered_map<const IMAGE_STATE *, layer_data::optional<ImageSubresourceLayoutMap>> CommandBufferImageLayoutMap;
171 
172 class CMD_BUFFER_STATE : public REFCOUNTED_NODE {
173   public:
174     VkCommandBufferAllocateInfo createInfo = {};
175     VkCommandBufferBeginInfo beginInfo;
176     VkCommandBufferInheritanceInfo inheritanceInfo;
177     // since command buffers can only be destroyed by their command pool, this does not need to be a shared_ptr
178     const COMMAND_POOL_STATE *command_pool;
179     ValidationStateTracker *dev_data;
180     bool hasDrawCmd;
181     bool hasTraceRaysCmd;
182     bool hasBuildAccelerationStructureCmd;
183     bool hasDispatchCmd;
184     bool unprotected;  // can't be used for protected memory
185 
186     CB_STATE state;         // Track cmd buffer update state
187     uint64_t commandCount;  // Number of commands recorded. Currently only used with VK_KHR_performance_query
188     uint64_t submitCount;   // Number of times CB has been submitted
189     typedef uint64_t ImageLayoutUpdateCount;
190     ImageLayoutUpdateCount image_layout_change_count;  // The sequence number for changes to image layout (for cached validation)
191     CBStatusFlags status;                              // Track status of various bindings on cmd buffer
192     CBStatusFlags static_status;                       // All state bits provided by current graphics pipeline
193                                                        // rather than dynamic state
194     CBStatusFlags dynamic_status;                      // dynamic state set up in pipeline
195     // Currently storing "lastBound" objects on per-CB basis
196     //  long-term may want to create caches of "lastBound" states and could have
197     //  each individual CMD_NODE referencing its own "lastBound" state
198     // Store last bound state for Gfx & Compute pipeline bind points
199     std::array<LAST_BOUND_STATE, BindPoint_Count> lastBound;  // index is LvlBindPoint.
200 
201     struct CmdDrawDispatchInfo {
202         CMD_TYPE cmd_type;
203         std::vector<std::pair<const uint32_t, DescriptorRequirement>> binding_infos;
204         VkFramebuffer framebuffer;
205         std::shared_ptr<std::vector<SUBPASS_INFO>> subpasses;
206         std::shared_ptr<std::vector<IMAGE_VIEW_STATE *>> attachments;
207     };
208     layer_data::unordered_map<VkDescriptorSet, std::vector<CmdDrawDispatchInfo>> validate_descriptorsets_in_queuesubmit;
209 
210     // If VK_NV_inherited_viewport_scissor is enabled and VkCommandBufferInheritanceViewportScissorInfoNV::viewportScissor2D is
211     // true, then is the nonempty list of viewports passed in pViewportDepths. Otherwise, this is empty.
212     std::vector<VkViewport> inheritedViewportDepths;
213 
214     // For each draw command D recorded to this command buffer, let
215     //  * g_D be the graphics pipeline used
216     //  * v_G be the viewportCount of g_D (0 if g_D disables rasterization or enables VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT)
217     //  * s_G be the scissorCount  of g_D (0 if g_D disables rasterization or enables VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT)
218     // Then this value is max(0, max(v_G for all D in cb), max(s_G for all D in cb))
219     uint32_t usedViewportScissorCount;
220     uint32_t pipelineStaticViewportCount;  // v_G for currently-bound graphics pipeline.
221     uint32_t pipelineStaticScissorCount;   // s_G for currently-bound graphics pipeline.
222 
223     uint32_t viewportMask;
224     uint32_t viewportWithCountMask;
225     uint32_t viewportWithCountCount;
226     uint32_t scissorMask;
227     uint32_t scissorWithCountMask;
228     uint32_t scissorWithCountCount;
229 
230     // Dynamic viewports set in this command buffer; if bit j of viewportMask is set then dynamicViewports[j] is valid, but the
231     // converse need not be true.
232     std::vector<VkViewport> dynamicViewports;
233 
234     // Bits set when binding graphics pipeline defining corresponding static state, or executing any secondary command buffer.
235     // Bits unset by calling a corresponding vkCmdSet[State] cmd.
236     uint32_t trashedViewportMask;
237     uint32_t trashedScissorMask;
238     bool trashedViewportCount;
239     bool trashedScissorCount;
240 
241     // True iff any draw command recorded to this command buffer consumes dynamic viewport/scissor with count state.
242     bool usedDynamicViewportCount;
243     bool usedDynamicScissorCount;
244 
245     uint32_t initial_device_mask;
246     VkPrimitiveTopology primitiveTopology;
247 
248     safe_VkRenderPassBeginInfo activeRenderPassBeginInfo;
249     std::shared_ptr<RENDER_PASS_STATE> activeRenderPass;
250     std::shared_ptr<std::vector<SUBPASS_INFO>> active_subpasses;
251     std::shared_ptr<std::vector<IMAGE_VIEW_STATE *>> active_attachments;
252     std::set<std::shared_ptr<IMAGE_VIEW_STATE>> attachments_view_states;
253 
254     VkSubpassContents activeSubpassContents;
255     uint32_t active_render_pass_device_mask;
256     uint32_t activeSubpass;
257     std::shared_ptr<FRAMEBUFFER_STATE> activeFramebuffer;
258     layer_data::unordered_set<std::shared_ptr<FRAMEBUFFER_STATE>> framebuffers;
259     // Unified data structs to track objects bound to this command buffer as well as object
260     //  dependencies that have been broken : either destroyed objects, or updated descriptor sets
261     BASE_NODE::NodeSet object_bindings;
262     layer_data::unordered_map<VulkanTypedHandle, LogObjectList> broken_bindings;
263 
264     QFOTransferBarrierSets<QFOBufferTransferBarrier> qfo_transfer_buffer_barriers;
265     QFOTransferBarrierSets<QFOImageTransferBarrier> qfo_transfer_image_barriers;
266 
267     layer_data::unordered_set<VkEvent> waitedEvents;
268     std::vector<VkEvent> writeEventsBeforeWait;
269     std::vector<VkEvent> events;
270     layer_data::unordered_set<QueryObject> activeQueries;
271     layer_data::unordered_set<QueryObject> startedQueries;
272     layer_data::unordered_set<QueryObject> resetQueries;
273     CommandBufferImageLayoutMap image_layout_map;
274     CBVertexBufferBindingInfo current_vertex_buffer_binding_info;
275     bool vertex_buffer_used;  // Track for perf warning to make sure any bound vtx buffer used
276     VkCommandBuffer primaryCommandBuffer;
277     // If primary, the secondary command buffers we will call.
278     // If secondary, the primary command buffers we will be called by.
279     layer_data::unordered_set<CMD_BUFFER_STATE *> linkedCommandBuffers;
280     // Validation functions run at primary CB queue submit time
281     using QueueCallback = std::function<bool(const ValidationStateTracker &device_data, const class QUEUE_STATE &queue_state,
282                                              const CMD_BUFFER_STATE &cb_state)>;
283     std::vector<QueueCallback> queue_submit_functions;
284     // Used by some layers to defer actions until vkCmdEndRenderPass time.
285     // Layers using this are responsible for inserting the callbacks into queue_submit_functions.
286     std::vector<QueueCallback> queue_submit_functions_after_render_pass;
287     // Validation functions run when secondary CB is executed in primary
288     std::vector<std::function<bool(const CMD_BUFFER_STATE &secondary, const CMD_BUFFER_STATE *primary, const FRAMEBUFFER_STATE *)>>
289         cmd_execute_commands_functions;
290     std::vector<
291         std::function<bool(const ValidationStateTracker *device_data, bool do_validate, EventToStageMap *localEventToStageMap)>>
292         eventUpdates;
293     std::vector<std::function<bool(const ValidationStateTracker *device_data, bool do_validate, VkQueryPool &firstPerfQueryPool,
294                                    uint32_t perfQueryPass, QueryMap *localQueryToStateMap)>>
295         queryUpdates;
296     layer_data::unordered_set<const cvdescriptorset::DescriptorSet *> validated_descriptor_sets;
297     layer_data::unordered_map<const cvdescriptorset::DescriptorSet *, cvdescriptorset::DescriptorSet::CachedValidation>
298         descriptorset_cache;
299     // Contents valid only after an index buffer is bound (CBSTATUS_INDEX_BUFFER_BOUND set)
300     IndexBufferBinding index_buffer_binding;
301     bool performance_lock_acquired = false;
302     bool performance_lock_released = false;
303 
304     // Cache of current insert label...
305     LoggingLabel debug_label;
306 
307     std::vector<uint8_t> push_constant_data;
308     PushConstantRangesId push_constant_data_ranges;
309 
310     std::map<VkShaderStageFlagBits, std::vector<uint8_t>>
311         push_constant_data_update;  // vector's value is enum PushConstantByteState.
312     VkPipelineLayout push_constant_pipeline_layout_set;
313 
314     // Used for Best Practices tracking
315     uint32_t small_indexed_draw_call_count;
316 
317     bool transform_feedback_active{false};
318     bool conditional_rendering_active{false};
319     bool conditional_rendering_inside_render_pass{false};
320     uint32_t conditional_rendering_subpass{0};
321 
322     CMD_BUFFER_STATE(ValidationStateTracker *, VkCommandBuffer cb, const VkCommandBufferAllocateInfo *pCreateInfo,
323                      const COMMAND_POOL_STATE *cmd_pool);
324 
~CMD_BUFFER_STATE()325     virtual ~CMD_BUFFER_STATE() { Destroy(); }
326 
327     void Destroy() override;
328 
commandBuffer()329     VkCommandBuffer commandBuffer() const { return handle_.Cast<VkCommandBuffer>(); }
330 
331     IMAGE_VIEW_STATE *GetActiveAttachmentImageViewState(uint32_t index);
332     const IMAGE_VIEW_STATE *GetActiveAttachmentImageViewState(uint32_t index) const;
333 
334     void AddChild(BASE_NODE *child_node);
335 
336     template <typename StateObject>
AddChild(std::shared_ptr<StateObject> & child_node)337     void AddChild(std::shared_ptr<StateObject> &child_node) {
338         AddChild(child_node.get());
339     }
340 
341     void RemoveChild(BASE_NODE *child_node);
342 
343     virtual void Reset();
344 
345     void IncrementResources();
346 
347     void ResetPushConstantDataIfIncompatible(const PIPELINE_LAYOUT_STATE *pipeline_layout_state);
348 
349     const ImageSubresourceLayoutMap *GetImageSubresourceLayoutMap(const IMAGE_STATE &image_state) const;
350     ImageSubresourceLayoutMap *GetImageSubresourceLayoutMap(const IMAGE_STATE &image_state);
351     const CommandBufferImageLayoutMap& GetImageSubresourceLayoutMap() const;
352 
GetQFOBarrierSets(const QFOImageTransferBarrier & type_tag)353     const QFOTransferBarrierSets<QFOImageTransferBarrier> &GetQFOBarrierSets(const QFOImageTransferBarrier &type_tag) const {
354         return qfo_transfer_image_barriers;
355     }
356 
GetQFOBarrierSets(const QFOBufferTransferBarrier & type_tag)357     const QFOTransferBarrierSets<QFOBufferTransferBarrier> &GetQFOBarrierSets(const QFOBufferTransferBarrier &type_tag) const {
358         return qfo_transfer_buffer_barriers;
359     }
360 
GetQFOBarrierSets(const QFOImageTransferBarrier & type_tag)361     QFOTransferBarrierSets<QFOImageTransferBarrier> &GetQFOBarrierSets(const QFOImageTransferBarrier &type_tag) {
362         return qfo_transfer_image_barriers;
363     }
364 
GetQFOBarrierSets(const QFOBufferTransferBarrier & type_tag)365     QFOTransferBarrierSets<QFOBufferTransferBarrier> &GetQFOBarrierSets(const QFOBufferTransferBarrier &type_tag) {
366         return qfo_transfer_buffer_barriers;
367     }
368 
GetCurrentPipeline(VkPipelineBindPoint pipelineBindPoint)369     PIPELINE_STATE *GetCurrentPipeline(VkPipelineBindPoint pipelineBindPoint) const {
370         const auto lv_bind_point = ConvertToLvlBindPoint(pipelineBindPoint);
371         return lastBound[lv_bind_point].pipeline_state;
372     }
373 
GetCurrentPipelineAndDesriptorSets(VkPipelineBindPoint pipelineBindPoint,const PIPELINE_STATE ** rtn_pipe,const std::vector<LAST_BOUND_STATE::PER_SET> ** rtn_sets)374     void GetCurrentPipelineAndDesriptorSets(VkPipelineBindPoint pipelineBindPoint, const PIPELINE_STATE **rtn_pipe,
375                                             const std::vector<LAST_BOUND_STATE::PER_SET> **rtn_sets) const {
376         const auto lv_bind_point = ConvertToLvlBindPoint(pipelineBindPoint);
377         const auto &last_bound_it = lastBound[lv_bind_point];
378         if (!last_bound_it.IsUsing()) {
379             return;
380         }
381         *rtn_pipe = last_bound_it.pipeline_state;
382         *rtn_sets = &(last_bound_it.per_set);
383     }
384 
GetQueueFlags()385     VkQueueFlags GetQueueFlags() const {
386 	    return command_pool->queue_flags;
387     }
388 
389     template <typename Barrier>
IsReleaseOp(const Barrier & barrier)390     inline bool IsReleaseOp(const Barrier &barrier) const {
391         return (IsTransferOp(barrier)) && (command_pool->queueFamilyIndex == barrier.srcQueueFamilyIndex);
392     }
393     template <typename Barrier>
IsAcquireOp(const Barrier & barrier)394     inline bool IsAcquireOp(const Barrier &barrier) const {
395         return (IsTransferOp(barrier)) && (command_pool->queueFamilyIndex == barrier.dstQueueFamilyIndex);
396     }
397 
398     void Begin(const VkCommandBufferBeginInfo *pBeginInfo);
399     void End(VkResult result);
400 
401     void BeginQuery(const QueryObject &query_obj);
402     void EndQuery(const QueryObject &query_obj);
403     void EndQueries(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount);
404     void ResetQueryPool(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount);
405 
406     void BeginRenderPass(CMD_TYPE cmd_type, const VkRenderPassBeginInfo *pRenderPassBegin, VkSubpassContents contents);
407     void NextSubpass(CMD_TYPE cmd_type, VkSubpassContents contents);
408     void EndRenderPass(CMD_TYPE cmd_type);
409 
410     void BeginRendering(CMD_TYPE cmd_type, const VkRenderingInfoKHR *pRenderingInfo);
411 
412     void ExecuteCommands(uint32_t commandBuffersCount, const VkCommandBuffer *pCommandBuffers);
413 
414     void UpdateLastBoundDescriptorSets(VkPipelineBindPoint pipeline_bind_point, const PIPELINE_LAYOUT_STATE *pipeline_layout,
415                                        uint32_t first_set, uint32_t set_count, const VkDescriptorSet *pDescriptorSets,
416                                        cvdescriptorset::DescriptorSet *push_descriptor_set, uint32_t dynamic_offset_count,
417                                        const uint32_t *p_dynamic_offsets);
418 
419     void PushDescriptorSetState(VkPipelineBindPoint pipelineBindPoint, PIPELINE_LAYOUT_STATE *pipeline_layout, uint32_t set,
420                                 uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites);
421 
422     void UpdateStateCmdDrawDispatchType(CMD_TYPE cmd_type, VkPipelineBindPoint bind_point);
423     void UpdateStateCmdDrawType(CMD_TYPE cmd_type, VkPipelineBindPoint bind_point);
424     void UpdateDrawState(CMD_TYPE cmd_type, const VkPipelineBindPoint bind_point);
425 
426     virtual void RecordCmd(CMD_TYPE cmd_type);
427     void RecordStateCmd(CMD_TYPE cmd_type, CBStatusFlags state_bits);
428     void RecordTransferCmd(CMD_TYPE cmd_type, std::shared_ptr<BINDABLE> &&buf1, std::shared_ptr<BINDABLE> &&buf2 = nullptr);
429     void RecordSetEvent(CMD_TYPE cmd_type, VkEvent event, VkPipelineStageFlags2KHR stageMask);
430     void RecordResetEvent(CMD_TYPE cmd_type, VkEvent event, VkPipelineStageFlags2KHR stageMask);
431     void RecordWaitEvents(CMD_TYPE cmd_type, uint32_t eventCount, const VkEvent *pEvents);
432     void RecordWriteTimestamp(CMD_TYPE cmd_type, VkPipelineStageFlags2KHR pipelineStage, VkQueryPool queryPool, uint32_t slot);
433 
434     void RecordBarriers(uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, uint32_t bufferMemoryBarrierCount,
435                         const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
436                         const VkImageMemoryBarrier *pImageMemoryBarriers);
437     void RecordBarriers(const VkDependencyInfoKHR &dep_info);
438 
439     void SetImageViewLayout(const IMAGE_VIEW_STATE &view_state, VkImageLayout layout, VkImageLayout layoutStencil);
440     void SetImageViewInitialLayout(const IMAGE_VIEW_STATE &view_state, VkImageLayout layout);
441 
442     void SetImageLayout(const IMAGE_STATE &image_state, const VkImageSubresourceRange &image_subresource_range,
443                         VkImageLayout layout, VkImageLayout expected_layout = kInvalidLayout);
444     void SetImageLayout(const IMAGE_STATE &image_state, const VkImageSubresourceLayers &image_subresource_layers,
445                         VkImageLayout layout);
446     void SetImageInitialLayout(VkImage image, const VkImageSubresourceRange &range, VkImageLayout layout);
447     void SetImageInitialLayout(const IMAGE_STATE &image_state, const VkImageSubresourceRange &range, VkImageLayout layout);
448     void SetImageInitialLayout(const IMAGE_STATE &image_state, const VkImageSubresourceLayers &layers, VkImageLayout layout);
449 
450     void Submit(uint32_t perf_submit_pass);
451     void Retire(uint32_t perf_submit_pass);
452 
GetDynamicColorAttachmentCount()453     uint32_t GetDynamicColorAttachmentCount() {
454         if (activeRenderPass) {
455             if (activeRenderPass->use_dynamic_rendering_inherited) {
456                 return activeRenderPass->inheritance_rendering_info.colorAttachmentCount;
457             }
458             if (activeRenderPass->use_dynamic_rendering) {
459                 return activeRenderPass->dynamic_rendering_begin_rendering_info.colorAttachmentCount;
460             }
461         }
462         return 0;
463     }
GetDynamicColorAttachmentImageIndex(uint32_t index)464     uint32_t GetDynamicColorAttachmentImageIndex(uint32_t index) { return index; }
GetDynamicColorResolveAttachmentImageIndex(uint32_t index)465     uint32_t GetDynamicColorResolveAttachmentImageIndex(uint32_t index) { return index + GetDynamicColorAttachmentCount(); }
GetDynamicDepthAttachmentImageIndex()466     uint32_t GetDynamicDepthAttachmentImageIndex() { return 2 * GetDynamicColorAttachmentCount(); }
GetDynamicDepthResolveAttachmentImageIndex()467     uint32_t GetDynamicDepthResolveAttachmentImageIndex() { return 2 * GetDynamicColorAttachmentCount() + 1; }
GetDynamicStencilAttachmentImageIndex()468     uint32_t GetDynamicStencilAttachmentImageIndex() { return 2 * GetDynamicColorAttachmentCount() + 2; }
GetDynamicStencilResolveAttachmentImageIndex()469     uint32_t GetDynamicStencilResolveAttachmentImageIndex() { return 2 * GetDynamicColorAttachmentCount() + 3; }
470 
471   protected:
472     void NotifyInvalidate(const BASE_NODE::NodeList &invalid_nodes, bool unlink) override;
473     void UpdateAttachmentsView(const VkRenderPassBeginInfo *pRenderPassBegin);
474 };
475 
476 // specializations for barriers that cannot do queue family ownership transfers
477 template <>
IsReleaseOp(const VkMemoryBarrier & barrier)478 inline bool CMD_BUFFER_STATE::IsReleaseOp(const VkMemoryBarrier &barrier) const {
479     return false;
480 }
481 template <>
IsReleaseOp(const VkMemoryBarrier2KHR & barrier)482 inline bool CMD_BUFFER_STATE::IsReleaseOp(const VkMemoryBarrier2KHR &barrier) const {
483     return false;
484 }
485 template <>
IsReleaseOp(const VkSubpassDependency2 & barrier)486 inline bool CMD_BUFFER_STATE::IsReleaseOp(const VkSubpassDependency2 &barrier) const {
487     return false;
488 }
489 template <>
IsAcquireOp(const VkMemoryBarrier & barrier)490 inline bool CMD_BUFFER_STATE::IsAcquireOp(const VkMemoryBarrier &barrier) const {
491     return false;
492 }
493 template <>
IsAcquireOp(const VkMemoryBarrier2KHR & barrier)494 inline bool CMD_BUFFER_STATE::IsAcquireOp(const VkMemoryBarrier2KHR &barrier) const {
495     return false;
496 }
497 template <>
IsAcquireOp(const VkSubpassDependency2 & barrier)498 inline bool CMD_BUFFER_STATE::IsAcquireOp(const VkSubpassDependency2 &barrier) const {
499     return false;
500 }
501