blob: c1e402631ac6300b419e3cbc671c872b8620fa5d [file] [log] [blame]
Jeremy Gebben4d51c552022-01-06 21:27:15 -07001/* Copyright (c) 2015-2022 The Khronos Group Inc.
2 * Copyright (c) 2015-2022 Valve Corporation
3 * Copyright (c) 2015-2022 LunarG, Inc.
4 * Copyright (C) 2015-2022 Google Inc.
Jeremy Gebben159b3cc2021-06-03 09:09:03 -06005 * 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
Jeremy Gebben1ec89332021-08-05 13:51:49 -060039struct SUBPASS_INFO;
40class FRAMEBUFFER_STATE;
Jeremy Gebben159b3cc2021-06-03 09:09:03 -060041class RENDER_PASS_STATE;
42class CoreChecks;
43class ValidationStateTracker;
44
Tony-LunarG285dbdc2022-07-15 09:42:54 -060045#ifdef VK_USE_PLATFORM_METAL_EXT
46static bool GetMetalExport(const VkEventCreateInfo *info) {
47 bool retval = false;
48 auto export_metal_object_info = LvlFindInChain<VkExportMetalObjectCreateInfoEXT>(info->pNext);
49 while (export_metal_object_info) {
50 if (export_metal_object_info->exportObjectType == VK_EXPORT_METAL_OBJECT_TYPE_METAL_SHARED_EVENT_BIT_EXT) {
51 retval = true;
52 break;
53 }
54 export_metal_object_info = LvlFindInChain<VkExportMetalObjectCreateInfoEXT>(export_metal_object_info->pNext);
55 }
56 return retval;
57}
58#endif // VK_USE_PLATFORM_METAL_EXT
59
Jeremy Gebben159b3cc2021-06-03 09:09:03 -060060class EVENT_STATE : public BASE_NODE {
61 public:
62 int write_in_use;
Tony-LunarG285dbdc2022-07-15 09:42:54 -060063#ifdef VK_USE_PLATFORM_METAL_EXT
64 const bool metal_event_export;
65#endif // VK_USE_PLATFORM_METAL_EXT
Jeremy Gebben159b3cc2021-06-03 09:09:03 -060066 VkPipelineStageFlags2KHR stageMask = VkPipelineStageFlags2KHR(0);
67 VkEventCreateFlags flags;
Tony-LunarG285dbdc2022-07-15 09:42:54 -060068
69 EVENT_STATE(VkEvent event_, const VkEventCreateInfo *pCreateInfo)
sjfricke52defd42022-08-08 16:37:46 +090070 : BASE_NODE(event_, kVulkanObjectTypeEvent),
71 write_in_use(0),
Tony-LunarGffb5b522022-06-15 15:49:27 -060072#ifdef VK_USE_PLATFORM_METAL_EXT
sjfricke52defd42022-08-08 16:37:46 +090073 metal_event_export(GetMetalExport(pCreateInfo)),
Tony-LunarG285dbdc2022-07-15 09:42:54 -060074#endif // VK_USE_PLATFORM_METAL_EXT
sjfricke52defd42022-08-08 16:37:46 +090075 flags(pCreateInfo->flags) {
76 }
Jeremy Gebben159b3cc2021-06-03 09:09:03 -060077
78 VkEvent event() const { return handle_.Cast<VkEvent>(); }
79};
80
81// Only CoreChecks uses this, but the state tracker stores it.
82constexpr static auto kInvalidLayout = image_layout_map::kInvalidLayout;
83using ImageSubresourceLayoutMap = image_layout_map::ImageSubresourceLayoutMap;
84typedef layer_data::unordered_map<VkEvent, VkPipelineStageFlags2KHR> EventToStageMap;
85
86// Track command pools and their command buffers
87class COMMAND_POOL_STATE : public BASE_NODE {
88 public:
Jeremy Gebbencd7fa282021-10-27 10:25:32 -060089 ValidationStateTracker *dev_data;
Jeremy Gebben1ec89332021-08-05 13:51:49 -060090 const VkCommandPoolCreateFlags createFlags;
91 const uint32_t queueFamilyIndex;
92 const VkQueueFlags queue_flags;
93 const bool unprotected; // can't be used for protected memory
Jeremy Gebben159b3cc2021-06-03 09:09:03 -060094 // Cmd buffers allocated from this pool
Jeremy Gebbencd7fa282021-10-27 10:25:32 -060095 layer_data::unordered_map<VkCommandBuffer, CMD_BUFFER_STATE *> commandBuffers;
Jeremy Gebben159b3cc2021-06-03 09:09:03 -060096
Jeremy Gebbencd7fa282021-10-27 10:25:32 -060097 COMMAND_POOL_STATE(ValidationStateTracker *dev, VkCommandPool cp, const VkCommandPoolCreateInfo *pCreateInfo,
98 VkQueueFlags flags);
99 virtual ~COMMAND_POOL_STATE() { Destroy(); }
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600100
101 VkCommandPool commandPool() const { return handle_.Cast<VkCommandPool>(); }
102
Jeremy Gebbencd7fa282021-10-27 10:25:32 -0600103 void Allocate(const VkCommandBufferAllocateInfo *create_info, const VkCommandBuffer *command_buffers);
104 void Free(uint32_t count, const VkCommandBuffer *command_buffers);
105 void Reset();
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600106
Jeremy Gebbencd7fa282021-10-27 10:25:32 -0600107 void Destroy() override;
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600108};
109
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600110// Autogenerated as part of the command_validation.h codegen
111const char *CommandTypeString(CMD_TYPE type);
112
113enum CB_STATE {
114 CB_NEW, // Newly created CB w/o any cmds
115 CB_RECORDING, // BeginCB has been called on this CB
116 CB_RECORDED, // EndCB has been called on this CB
117 CB_INVALID_COMPLETE, // had a complete recording, but was since invalidated
118 CB_INVALID_INCOMPLETE, // fouled before recording was completed
119};
120
121// CB Status -- used to track status of various bindings on cmd buffer objects
122typedef uint64_t CBStatusFlags;
123enum CBStatusFlagBits : uint64_t {
124 // clang-format off
125 CBSTATUS_NONE = 0x00000000, // No status is set
126 CBSTATUS_LINE_WIDTH_SET = 0x00000001, // Line width has been set
127 CBSTATUS_DEPTH_BIAS_SET = 0x00000002, // Depth bias has been set
128 CBSTATUS_BLEND_CONSTANTS_SET = 0x00000004, // Blend constants state has been set
129 CBSTATUS_DEPTH_BOUNDS_SET = 0x00000008, // Depth bounds state object has been set
130 CBSTATUS_STENCIL_READ_MASK_SET = 0x00000010, // Stencil read mask has been set
131 CBSTATUS_STENCIL_WRITE_MASK_SET = 0x00000020, // Stencil write mask has been set
132 CBSTATUS_STENCIL_REFERENCE_SET = 0x00000040, // Stencil reference has been set
133 CBSTATUS_VIEWPORT_SET = 0x00000080,
134 CBSTATUS_SCISSOR_SET = 0x00000100,
135 CBSTATUS_INDEX_BUFFER_BOUND = 0x00000200, // Index buffer has been set
136 CBSTATUS_EXCLUSIVE_SCISSOR_SET = 0x00000400,
137 CBSTATUS_SHADING_RATE_PALETTE_SET = 0x00000800,
138 CBSTATUS_LINE_STIPPLE_SET = 0x00001000,
139 CBSTATUS_VIEWPORT_W_SCALING_SET = 0x00002000,
140 CBSTATUS_CULL_MODE_SET = 0x00004000,
141 CBSTATUS_FRONT_FACE_SET = 0x00008000,
142 CBSTATUS_PRIMITIVE_TOPOLOGY_SET = 0x00010000,
143 CBSTATUS_VIEWPORT_WITH_COUNT_SET = 0x00020000,
144 CBSTATUS_SCISSOR_WITH_COUNT_SET = 0x00040000,
145 CBSTATUS_VERTEX_INPUT_BINDING_STRIDE_SET = 0x00080000,
146 CBSTATUS_DEPTH_TEST_ENABLE_SET = 0x00100000,
147 CBSTATUS_DEPTH_WRITE_ENABLE_SET = 0x00200000,
148 CBSTATUS_DEPTH_COMPARE_OP_SET = 0x00400000,
149 CBSTATUS_DEPTH_BOUNDS_TEST_ENABLE_SET = 0x00800000,
150 CBSTATUS_STENCIL_TEST_ENABLE_SET = 0x01000000,
151 CBSTATUS_STENCIL_OP_SET = 0x02000000,
152 CBSTATUS_DISCARD_RECTANGLE_SET = 0x04000000,
153 CBSTATUS_SAMPLE_LOCATIONS_SET = 0x08000000,
154 CBSTATUS_COARSE_SAMPLE_ORDER_SET = 0x10000000,
155 CBSTATUS_PATCH_CONTROL_POINTS_SET = 0x20000000,
156 CBSTATUS_RASTERIZER_DISCARD_ENABLE_SET = 0x40000000,
157 CBSTATUS_DEPTH_BIAS_ENABLE_SET = 0x80000000,
158 CBSTATUS_LOGIC_OP_SET = 0x100000000,
159 CBSTATUS_PRIMITIVE_RESTART_ENABLE_SET = 0x200000000,
160 CBSTATUS_VERTEX_INPUT_SET = 0x400000000,
ziga-lunarg67b7c392022-03-26 01:45:34 +0100161 CBSTATUS_COLOR_WRITE_ENABLE_SET = 0x800000000,
162 CBSTATUS_ALL_STATE_SET = 0xFFFFFFDFF, // All state set (intentionally exclude index buffer)
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600163 // clang-format on
164};
165
166VkDynamicState ConvertToDynamicState(CBStatusFlagBits flag);
167CBStatusFlagBits ConvertToCBStatusFlagBits(VkDynamicState state);
168std::string DynamicStateString(CBStatusFlags input_value);
169
170struct BufferBinding {
171 std::shared_ptr<BUFFER_STATE> buffer_state;
172 VkDeviceSize size;
173 VkDeviceSize offset;
174 VkDeviceSize stride;
175
176 BufferBinding() : buffer_state(), size(0), offset(0), stride(0) {}
177 virtual ~BufferBinding() {}
178
179 virtual void reset() { *this = BufferBinding(); }
180};
181
182struct IndexBufferBinding : BufferBinding {
183 VkIndexType index_type;
184
185 IndexBufferBinding() : BufferBinding(), index_type(static_cast<VkIndexType>(0)) {}
186 virtual ~IndexBufferBinding() {}
187
188 virtual void reset() override { *this = IndexBufferBinding(); }
189};
190
191struct CBVertexBufferBindingInfo {
192 std::vector<BufferBinding> vertex_buffer_bindings;
193};
194
Jeremy Gebben4a8881f2022-01-10 17:04:30 -0700195typedef layer_data::unordered_map<const IMAGE_STATE *, std::shared_ptr<ImageSubresourceLayoutMap>> CommandBufferImageLayoutMap;
196
197typedef layer_data::unordered_map<const GlobalImageLayoutRangeMap *, std::shared_ptr<ImageSubresourceLayoutMap>>
198 CommandBufferAliasedLayoutMap;
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600199
200class CMD_BUFFER_STATE : public REFCOUNTED_NODE {
201 public:
202 VkCommandBufferAllocateInfo createInfo = {};
203 VkCommandBufferBeginInfo beginInfo;
204 VkCommandBufferInheritanceInfo inheritanceInfo;
Jeremy Gebbencd7fa282021-10-27 10:25:32 -0600205 // since command buffers can only be destroyed by their command pool, this does not need to be a shared_ptr
206 const COMMAND_POOL_STATE *command_pool;
Jeremy Gebben1ec89332021-08-05 13:51:49 -0600207 ValidationStateTracker *dev_data;
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600208 bool unprotected; // can't be used for protected memory
ziga-lunarg0acda6f2022-04-25 22:41:52 +0200209 bool hasRenderPassInstance;
210 bool suspendsRenderPassInstance;
211 bool resumesRenderPassInstance;
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600212
sjfricke52defd42022-08-08 16:37:46 +0900213 // Track if certain commands have been called at least once in lifetime of the command buffer
214 // primary command buffers values are set true if a secondary command buffer has a command
215 bool has_draw_cmd;
Hans-Kristian Arntzen0f234382022-06-16 12:37:43 +0200216 bool has_draw_cmd_in_current_render_pass;
sjfricke52defd42022-08-08 16:37:46 +0900217 bool has_dispatch_cmd;
218 bool has_trace_rays_cmd;
219 bool has_build_as_cmd;
220
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600221 CB_STATE state; // Track cmd buffer update state
222 uint64_t commandCount; // Number of commands recorded. Currently only used with VK_KHR_performance_query
223 uint64_t submitCount; // Number of times CB has been submitted
Hans-Kristian Arntzen0f234382022-06-16 12:37:43 +0200224 bool pipeline_bound = false; // True if CmdBindPipeline has been called on this command buffer, false otherwise
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600225 typedef uint64_t ImageLayoutUpdateCount;
226 ImageLayoutUpdateCount image_layout_change_count; // The sequence number for changes to image layout (for cached validation)
227 CBStatusFlags status; // Track status of various bindings on cmd buffer
228 CBStatusFlags static_status; // All state bits provided by current graphics pipeline
229 // rather than dynamic state
230 CBStatusFlags dynamic_status; // dynamic state set up in pipeline
Tony-LunarG40b33882021-12-02 12:40:11 -0700231 std::string begin_rendering_func_name;
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600232 // Currently storing "lastBound" objects on per-CB basis
233 // long-term may want to create caches of "lastBound" states and could have
234 // each individual CMD_NODE referencing its own "lastBound" state
235 // Store last bound state for Gfx & Compute pipeline bind points
236 std::array<LAST_BOUND_STATE, BindPoint_Count> lastBound; // index is LvlBindPoint.
237
John Zulauf5dea8842022-04-12 14:05:47 -0600238 // Use the casting boilerplate from BASE_NODE to implement the derived shared_from_this
239 std::shared_ptr<const CMD_BUFFER_STATE> shared_from_this() const { return SharedFromThisImpl(this); }
240 std::shared_ptr<CMD_BUFFER_STATE> shared_from_this() { return SharedFromThisImpl(this); }
241
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600242 struct CmdDrawDispatchInfo {
243 CMD_TYPE cmd_type;
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600244 std::vector<std::pair<const uint32_t, DescriptorRequirement>> binding_infos;
245 VkFramebuffer framebuffer;
246 std::shared_ptr<std::vector<SUBPASS_INFO>> subpasses;
247 std::shared_ptr<std::vector<IMAGE_VIEW_STATE *>> attachments;
248 };
249 layer_data::unordered_map<VkDescriptorSet, std::vector<CmdDrawDispatchInfo>> validate_descriptorsets_in_queuesubmit;
250
251 // If VK_NV_inherited_viewport_scissor is enabled and VkCommandBufferInheritanceViewportScissorInfoNV::viewportScissor2D is
252 // true, then is the nonempty list of viewports passed in pViewportDepths. Otherwise, this is empty.
253 std::vector<VkViewport> inheritedViewportDepths;
254
255 // For each draw command D recorded to this command buffer, let
256 // * g_D be the graphics pipeline used
257 // * v_G be the viewportCount of g_D (0 if g_D disables rasterization or enables VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT)
258 // * s_G be the scissorCount of g_D (0 if g_D disables rasterization or enables VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT)
259 // Then this value is max(0, max(v_G for all D in cb), max(s_G for all D in cb))
260 uint32_t usedViewportScissorCount;
261 uint32_t pipelineStaticViewportCount; // v_G for currently-bound graphics pipeline.
262 uint32_t pipelineStaticScissorCount; // s_G for currently-bound graphics pipeline.
263
264 uint32_t viewportMask;
265 uint32_t viewportWithCountMask;
266 uint32_t viewportWithCountCount;
267 uint32_t scissorMask;
268 uint32_t scissorWithCountMask;
269 uint32_t scissorWithCountCount;
270
271 // Dynamic viewports set in this command buffer; if bit j of viewportMask is set then dynamicViewports[j] is valid, but the
272 // converse need not be true.
273 std::vector<VkViewport> dynamicViewports;
274
275 // Bits set when binding graphics pipeline defining corresponding static state, or executing any secondary command buffer.
276 // Bits unset by calling a corresponding vkCmdSet[State] cmd.
277 uint32_t trashedViewportMask;
278 uint32_t trashedScissorMask;
279 bool trashedViewportCount;
280 bool trashedScissorCount;
281
282 // True iff any draw command recorded to this command buffer consumes dynamic viewport/scissor with count state.
283 bool usedDynamicViewportCount;
284 bool usedDynamicScissorCount;
285
286 uint32_t initial_device_mask;
287 VkPrimitiveTopology primitiveTopology;
288
Nathaniel Cesario8d5c9d92022-07-25 12:59:16 -0600289 bool rasterization_disabled = false;
290
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600291 safe_VkRenderPassBeginInfo activeRenderPassBeginInfo;
292 std::shared_ptr<RENDER_PASS_STATE> activeRenderPass;
293 std::shared_ptr<std::vector<SUBPASS_INFO>> active_subpasses;
294 std::shared_ptr<std::vector<IMAGE_VIEW_STATE *>> active_attachments;
295 std::set<std::shared_ptr<IMAGE_VIEW_STATE>> attachments_view_states;
296
297 VkSubpassContents activeSubpassContents;
298 uint32_t active_render_pass_device_mask;
299 uint32_t activeSubpass;
300 std::shared_ptr<FRAMEBUFFER_STATE> activeFramebuffer;
301 layer_data::unordered_set<std::shared_ptr<FRAMEBUFFER_STATE>> framebuffers;
302 // Unified data structs to track objects bound to this command buffer as well as object
303 // dependencies that have been broken : either destroyed objects, or updated descriptor sets
Jeremy Gebben610d3a62022-01-01 12:53:17 -0700304 layer_data::unordered_set<std::shared_ptr<BASE_NODE>> object_bindings;
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600305 layer_data::unordered_map<VulkanTypedHandle, LogObjectList> broken_bindings;
306
307 QFOTransferBarrierSets<QFOBufferTransferBarrier> qfo_transfer_buffer_barriers;
308 QFOTransferBarrierSets<QFOImageTransferBarrier> qfo_transfer_image_barriers;
309
310 layer_data::unordered_set<VkEvent> waitedEvents;
311 std::vector<VkEvent> writeEventsBeforeWait;
312 std::vector<VkEvent> events;
313 layer_data::unordered_set<QueryObject> activeQueries;
314 layer_data::unordered_set<QueryObject> startedQueries;
315 layer_data::unordered_set<QueryObject> resetQueries;
ziga-lunarg96c7d822022-02-28 19:39:17 +0100316 layer_data::unordered_set<QueryObject> updatedQueries;
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600317 CommandBufferImageLayoutMap image_layout_map;
Jeremy Gebben4a8881f2022-01-10 17:04:30 -0700318 CommandBufferAliasedLayoutMap aliased_image_layout_map; // storage for potentially aliased images
319
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600320 CBVertexBufferBindingInfo current_vertex_buffer_binding_info;
321 bool vertex_buffer_used; // Track for perf warning to make sure any bound vtx buffer used
322 VkCommandBuffer primaryCommandBuffer;
323 // If primary, the secondary command buffers we will call.
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600324 layer_data::unordered_set<CMD_BUFFER_STATE *> linkedCommandBuffers;
325 // Validation functions run at primary CB queue submit time
Jeremy Gebbene5361dd2021-11-18 14:23:56 -0700326 using QueueCallback = std::function<bool(const ValidationStateTracker &device_data, const class QUEUE_STATE &queue_state,
327 const CMD_BUFFER_STATE &cb_state)>;
328 std::vector<QueueCallback> queue_submit_functions;
Hans-Kristian Arntzen59c2c3f2021-06-14 11:40:12 +0200329 // Used by some layers to defer actions until vkCmdEndRenderPass time.
330 // Layers using this are responsible for inserting the callbacks into queue_submit_functions.
Jeremy Gebbene5361dd2021-11-18 14:23:56 -0700331 std::vector<QueueCallback> queue_submit_functions_after_render_pass;
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600332 // Validation functions run when secondary CB is executed in primary
Jeremy Gebben057f9d52021-11-05 14:12:31 -0600333 std::vector<std::function<bool(const CMD_BUFFER_STATE &secondary, const CMD_BUFFER_STATE *primary, const FRAMEBUFFER_STATE *)>>
334 cmd_execute_commands_functions;
Jeremy Gebben332d4dd2022-01-01 12:40:02 -0700335 std::vector<std::function<bool(CMD_BUFFER_STATE &cb, bool do_validate, EventToStageMap *localEventToStageMap)>> eventUpdates;
Jeremy Gebben221bb372022-09-19 14:19:32 -0600336 std::vector<std::function<bool(CMD_BUFFER_STATE &cb, bool do_validate, VkQueryPool &firstPerfQueryPool, uint32_t perfQueryPass,
337 QueryMap *localQueryToStateMap)>>
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600338 queryUpdates;
Jeremy Gebben87db52f2021-10-14 13:55:09 -0600339 layer_data::unordered_map<const cvdescriptorset::DescriptorSet *, cvdescriptorset::DescriptorSet::CachedValidation>
340 descriptorset_cache;
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600341 // Contents valid only after an index buffer is bound (CBSTATUS_INDEX_BUFFER_BOUND set)
342 IndexBufferBinding index_buffer_binding;
343 bool performance_lock_acquired = false;
344 bool performance_lock_released = false;
345
346 // Cache of current insert label...
347 LoggingLabel debug_label;
348
349 std::vector<uint8_t> push_constant_data;
350 PushConstantRangesId push_constant_data_ranges;
351
352 std::map<VkShaderStageFlagBits, std::vector<uint8_t>>
353 push_constant_data_update; // vector's value is enum PushConstantByteState.
354 VkPipelineLayout push_constant_pipeline_layout_set;
355
356 // Used for Best Practices tracking
357 uint32_t small_indexed_draw_call_count;
358
359 bool transform_feedback_active{false};
ziga-lunarg40f5fbc2021-08-14 23:06:41 +0200360 bool conditional_rendering_active{false};
ziga-lunarg39eeaf22021-09-03 19:12:44 +0200361 bool conditional_rendering_inside_render_pass{false};
362 uint32_t conditional_rendering_subpass{0};
ziga-lunarg67b7c392022-03-26 01:45:34 +0100363 uint32_t dynamicColorWriteEnableAttachmentCount{0};
Jeremy Gebben332d4dd2022-01-01 12:40:02 -0700364 mutable ReadWriteLock lock;
365 ReadLockGuard ReadLock() const { return ReadLockGuard(lock); }
366 WriteLockGuard WriteLock() { return WriteLockGuard(lock); }
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600367
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600368 CMD_BUFFER_STATE(ValidationStateTracker *, VkCommandBuffer cb, const VkCommandBufferAllocateInfo *pCreateInfo,
Jeremy Gebbencd7fa282021-10-27 10:25:32 -0600369 const COMMAND_POOL_STATE *cmd_pool);
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600370
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600371 virtual ~CMD_BUFFER_STATE() { Destroy(); }
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600372
373 void Destroy() override;
374
375 VkCommandBuffer commandBuffer() const { return handle_.Cast<VkCommandBuffer>(); }
376
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600377 IMAGE_VIEW_STATE *GetActiveAttachmentImageViewState(uint32_t index);
378 const IMAGE_VIEW_STATE *GetActiveAttachmentImageViewState(uint32_t index) const;
379
Jeremy Gebben610d3a62022-01-01 12:53:17 -0700380 void AddChild(std::shared_ptr<BASE_NODE> &base_node);
Jeremy Gebben9f537102021-10-05 16:37:12 -0600381 template <typename StateObject>
382 void AddChild(std::shared_ptr<StateObject> &child_node) {
Jeremy Gebben610d3a62022-01-01 12:53:17 -0700383 auto base = std::static_pointer_cast<BASE_NODE>(child_node);
384 AddChild(base);
Jeremy Gebben9f537102021-10-05 16:37:12 -0600385 }
386
Jeremy Gebben610d3a62022-01-01 12:53:17 -0700387 void RemoveChild(std::shared_ptr<BASE_NODE> &base_node);
388 template <typename StateObject>
389 void RemoveChild(std::shared_ptr<StateObject> &child_node) {
390 auto base = std::static_pointer_cast<BASE_NODE>(child_node);
391 RemoveChild(base);
392 }
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600393
Jeremy Gebben3d22d582021-08-11 15:37:58 -0600394 virtual void Reset();
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600395
Jeremy Gebben1ec89332021-08-05 13:51:49 -0600396 void IncrementResources();
397
398 void ResetPushConstantDataIfIncompatible(const PIPELINE_LAYOUT_STATE *pipeline_layout_state);
399
Jeremy Gebben6335df62021-11-01 10:50:13 -0600400 const ImageSubresourceLayoutMap *GetImageSubresourceLayoutMap(const IMAGE_STATE &image_state) const;
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600401 ImageSubresourceLayoutMap *GetImageSubresourceLayoutMap(const IMAGE_STATE &image_state);
ziga-lunarg189ae5d2021-10-19 13:09:58 +0200402 const CommandBufferImageLayoutMap& GetImageSubresourceLayoutMap() const;
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600403
404 const QFOTransferBarrierSets<QFOImageTransferBarrier> &GetQFOBarrierSets(const QFOImageTransferBarrier &type_tag) const {
405 return qfo_transfer_image_barriers;
406 }
407
408 const QFOTransferBarrierSets<QFOBufferTransferBarrier> &GetQFOBarrierSets(const QFOBufferTransferBarrier &type_tag) const {
409 return qfo_transfer_buffer_barriers;
410 }
411
412 QFOTransferBarrierSets<QFOImageTransferBarrier> &GetQFOBarrierSets(const QFOImageTransferBarrier &type_tag) {
413 return qfo_transfer_image_barriers;
414 }
415
416 QFOTransferBarrierSets<QFOBufferTransferBarrier> &GetQFOBarrierSets(const QFOBufferTransferBarrier &type_tag) {
417 return qfo_transfer_buffer_barriers;
418 }
419
420 PIPELINE_STATE *GetCurrentPipeline(VkPipelineBindPoint pipelineBindPoint) const {
421 const auto lv_bind_point = ConvertToLvlBindPoint(pipelineBindPoint);
422 return lastBound[lv_bind_point].pipeline_state;
423 }
424
425 void GetCurrentPipelineAndDesriptorSets(VkPipelineBindPoint pipelineBindPoint, const PIPELINE_STATE **rtn_pipe,
426 const std::vector<LAST_BOUND_STATE::PER_SET> **rtn_sets) const {
427 const auto lv_bind_point = ConvertToLvlBindPoint(pipelineBindPoint);
428 const auto &last_bound_it = lastBound[lv_bind_point];
429 if (!last_bound_it.IsUsing()) {
430 return;
431 }
432 *rtn_pipe = last_bound_it.pipeline_state;
433 *rtn_sets = &(last_bound_it.per_set);
434 }
435
436 VkQueueFlags GetQueueFlags() const {
437 return command_pool->queue_flags;
438 }
439
Jeremy Gebbenefead332021-06-18 08:22:44 -0600440 template <typename Barrier>
Jeremy Gebben7ba56152021-06-18 10:40:10 -0600441 inline bool IsReleaseOp(const Barrier &barrier) const {
442 return (IsTransferOp(barrier)) && (command_pool->queueFamilyIndex == barrier.srcQueueFamilyIndex);
443 }
444 template <typename Barrier>
445 inline bool IsAcquireOp(const Barrier &barrier) const {
446 return (IsTransferOp(barrier)) && (command_pool->queueFamilyIndex == barrier.dstQueueFamilyIndex);
Jeremy Gebbenefead332021-06-18 08:22:44 -0600447 }
448
Jeremy Gebben1ec89332021-08-05 13:51:49 -0600449 void Begin(const VkCommandBufferBeginInfo *pBeginInfo);
450 void End(VkResult result);
451
452 void BeginQuery(const QueryObject &query_obj);
453 void EndQuery(const QueryObject &query_obj);
454 void EndQueries(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount);
455 void ResetQueryPool(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount);
Jeremy Gebbenc615f792022-09-19 16:31:24 -0600456 bool UpdatesQuery(const QueryObject &query_obj) const;
Jeremy Gebben1ec89332021-08-05 13:51:49 -0600457
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600458 void BeginRenderPass(CMD_TYPE cmd_type, const VkRenderPassBeginInfo *pRenderPassBegin, VkSubpassContents contents);
459 void NextSubpass(CMD_TYPE cmd_type, VkSubpassContents contents);
460 void EndRenderPass(CMD_TYPE cmd_type);
Jeremy Gebben1ec89332021-08-05 13:51:49 -0600461
Tony-LunarG40b33882021-12-02 12:40:11 -0700462 void BeginRendering(CMD_TYPE cmd_type, const VkRenderingInfo *pRenderingInfo);
amhagana448ea52021-11-02 14:09:14 -0400463
Jeremy Gebben1ec89332021-08-05 13:51:49 -0600464 void ExecuteCommands(uint32_t commandBuffersCount, const VkCommandBuffer *pCommandBuffers);
465
466 void UpdateLastBoundDescriptorSets(VkPipelineBindPoint pipeline_bind_point, const PIPELINE_LAYOUT_STATE *pipeline_layout,
467 uint32_t first_set, uint32_t set_count, const VkDescriptorSet *pDescriptorSets,
Jeremy Gebben4d51c552022-01-06 21:27:15 -0700468 std::shared_ptr<cvdescriptorset::DescriptorSet> &push_descriptor_set,
469 uint32_t dynamic_offset_count, const uint32_t *p_dynamic_offsets);
Jeremy Gebben1ec89332021-08-05 13:51:49 -0600470
471 void PushDescriptorSetState(VkPipelineBindPoint pipelineBindPoint, PIPELINE_LAYOUT_STATE *pipeline_layout, uint32_t set,
472 uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites);
473
sjfricke52defd42022-08-08 16:37:46 +0900474 void UpdateDrawCmd(CMD_TYPE cmd_type);
475 void UpdateDispatchCmd(CMD_TYPE cmd_type);
476 void UpdateTraceRayCmd(CMD_TYPE cmd_type);
477 void UpdatePipelineState(CMD_TYPE cmd_type, const VkPipelineBindPoint bind_point);
Jeremy Gebben1ec89332021-08-05 13:51:49 -0600478
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600479 virtual void RecordCmd(CMD_TYPE cmd_type);
480 void RecordStateCmd(CMD_TYPE cmd_type, CBStatusFlags state_bits);
ziga-lunarg67b7c392022-03-26 01:45:34 +0100481 void RecordColorWriteEnableStateCmd(CMD_TYPE cmd_type, CBStatusFlags state_bits, uint32_t attachment_count);
Jeremy Gebben9f537102021-10-05 16:37:12 -0600482 void RecordTransferCmd(CMD_TYPE cmd_type, std::shared_ptr<BINDABLE> &&buf1, std::shared_ptr<BINDABLE> &&buf2 = nullptr);
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -0600483 void RecordSetEvent(CMD_TYPE cmd_type, VkEvent event, VkPipelineStageFlags2KHR stageMask);
484 void RecordResetEvent(CMD_TYPE cmd_type, VkEvent event, VkPipelineStageFlags2KHR stageMask);
Jeremy Gebben332d4dd2022-01-01 12:40:02 -0700485 virtual void RecordWaitEvents(CMD_TYPE cmd_type, uint32_t eventCount, const VkEvent *pEvents,
486 VkPipelineStageFlags2KHR src_stage_mask);
Jeremy Gebbencefa7fd2021-08-17 13:44:47 -0600487 void RecordWriteTimestamp(CMD_TYPE cmd_type, VkPipelineStageFlags2KHR pipelineStage, VkQueryPool queryPool, uint32_t slot);
488
489 void RecordBarriers(uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, uint32_t bufferMemoryBarrierCount,
490 const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
491 const VkImageMemoryBarrier *pImageMemoryBarriers);
492 void RecordBarriers(const VkDependencyInfoKHR &dep_info);
Jeremy Gebben10a0ed12021-08-17 09:54:29 -0600493
Jeremy Gebben1ec89332021-08-05 13:51:49 -0600494 void SetImageViewLayout(const IMAGE_VIEW_STATE &view_state, VkImageLayout layout, VkImageLayout layoutStencil);
495 void SetImageViewInitialLayout(const IMAGE_VIEW_STATE &view_state, VkImageLayout layout);
496
497 void SetImageLayout(const IMAGE_STATE &image_state, const VkImageSubresourceRange &image_subresource_range,
498 VkImageLayout layout, VkImageLayout expected_layout = kInvalidLayout);
499 void SetImageLayout(const IMAGE_STATE &image_state, const VkImageSubresourceLayers &image_subresource_layers,
500 VkImageLayout layout);
501 void SetImageInitialLayout(VkImage image, const VkImageSubresourceRange &range, VkImageLayout layout);
502 void SetImageInitialLayout(const IMAGE_STATE &image_state, const VkImageSubresourceRange &range, VkImageLayout layout);
503 void SetImageInitialLayout(const IMAGE_STATE &image_state, const VkImageSubresourceLayers &layers, VkImageLayout layout);
504
Jeremy Gebben57642982021-09-14 14:14:55 -0600505 void Submit(uint32_t perf_submit_pass);
ziga-lunarg96c7d822022-02-28 19:39:17 +0100506 void Retire(uint32_t perf_submit_pass, const std::function<bool(const QueryObject &)> &is_query_updated_after);
Jeremy Gebben57642982021-09-14 14:14:55 -0600507
amhagana448ea52021-11-02 14:09:14 -0400508 uint32_t GetDynamicColorAttachmentCount() {
509 if (activeRenderPass) {
510 if (activeRenderPass->use_dynamic_rendering_inherited) {
511 return activeRenderPass->inheritance_rendering_info.colorAttachmentCount;
512 }
513 if (activeRenderPass->use_dynamic_rendering) {
Aaron Hagan92a44f82021-11-19 09:34:56 -0500514 return activeRenderPass->dynamic_rendering_begin_rendering_info.colorAttachmentCount;
amhagana448ea52021-11-02 14:09:14 -0400515 }
516 }
517 return 0;
518 }
519 uint32_t GetDynamicColorAttachmentImageIndex(uint32_t index) { return index; }
520 uint32_t GetDynamicColorResolveAttachmentImageIndex(uint32_t index) { return index + GetDynamicColorAttachmentCount(); }
521 uint32_t GetDynamicDepthAttachmentImageIndex() { return 2 * GetDynamicColorAttachmentCount(); }
522 uint32_t GetDynamicDepthResolveAttachmentImageIndex() { return 2 * GetDynamicColorAttachmentCount() + 1; }
523 uint32_t GetDynamicStencilAttachmentImageIndex() { return 2 * GetDynamicColorAttachmentCount() + 2; }
524 uint32_t GetDynamicStencilResolveAttachmentImageIndex() { return 2 * GetDynamicColorAttachmentCount() + 3; }
525
Nathaniel Cesario8d5c9d92022-07-25 12:59:16 -0600526 bool RasterizationDisabled() const;
Nathaniel Cesario62f03592022-07-11 09:19:20 -0600527 inline void BindPipeline(LvlBindPoint bind_point, PIPELINE_STATE *pipe_state) {
528 lastBound[bind_point].pipeline_state = pipe_state;
529 pipeline_bound = true;
530 }
Nathaniel Cesario8d5c9d92022-07-25 12:59:16 -0600531
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600532 protected:
Jeremy Gebbenc9a24032021-11-02 11:36:08 -0600533 void NotifyInvalidate(const BASE_NODE::NodeList &invalid_nodes, bool unlink) override;
Jeremy Gebben1ec89332021-08-05 13:51:49 -0600534 void UpdateAttachmentsView(const VkRenderPassBeginInfo *pRenderPassBegin);
aitor-lunarga131fca2022-02-17 22:55:55 +0100535 void UnbindResources();
Jeremy Gebben159b3cc2021-06-03 09:09:03 -0600536};
Jeremy Gebben7ba56152021-06-18 10:40:10 -0600537
538// specializations for barriers that cannot do queue family ownership transfers
539template <>
540inline bool CMD_BUFFER_STATE::IsReleaseOp(const VkMemoryBarrier &barrier) const {
541 return false;
542}
543template <>
544inline bool CMD_BUFFER_STATE::IsReleaseOp(const VkMemoryBarrier2KHR &barrier) const {
545 return false;
546}
547template <>
548inline bool CMD_BUFFER_STATE::IsReleaseOp(const VkSubpassDependency2 &barrier) const {
549 return false;
550}
551template <>
552inline bool CMD_BUFFER_STATE::IsAcquireOp(const VkMemoryBarrier &barrier) const {
553 return false;
554}
555template <>
556inline bool CMD_BUFFER_STATE::IsAcquireOp(const VkMemoryBarrier2KHR &barrier) const {
557 return false;
558}
559template <>
560inline bool CMD_BUFFER_STATE::IsAcquireOp(const VkSubpassDependency2 &barrier) const {
561 return false;
562}