blob: f709b093b6c252585a0cad97daf198d5bac4969b [file] [log] [blame]
John Zulauf3d84f1b2020-03-09 13:33:25 -06001/*
John Zulaufab7756b2020-12-29 16:10:16 -07002 * Copyright (c) 2019-2021 Valve Corporation
3 * Copyright (c) 2019-2021 LunarG, Inc.
John Zulauf9cb530d2019-09-30 14:14:10 -06004 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * Author: John Zulauf <jzulauf@lunarg.com>
John Zulaufab7756b2020-12-29 16:10:16 -070018 * Author: Locke Lin <locke@lunarg.com>
19 * Author: Jeremy Gebben <jeremyg@lunarg.com>
John Zulauf9cb530d2019-09-30 14:14:10 -060020 */
21
22#pragma once
23
John Zulauf7635de32020-05-29 17:14:15 -060024#include <limits>
John Zulauf9cb530d2019-09-30 14:14:10 -060025#include <memory>
John Zulauf9cb530d2019-09-30 14:14:10 -060026#include <vulkan/vulkan.h>
27
28#include "synchronization_validation_types.h"
29#include "state_tracker.h"
Jeremy Gebben159b3cc2021-06-03 09:09:03 -060030#include "cmd_buffer_state.h"
31#include "render_pass_state.h"
John Zulauf9cb530d2019-09-30 14:14:10 -060032
John Zulaufd5115702021-01-18 12:34:33 -070033class AccessContext;
John Zulauffaea0ee2021-01-14 14:01:32 -070034class CommandBufferAccessContext;
John Zulaufe7f6a5e2021-01-16 14:31:18 -070035using CommandBufferAccessContextShared = std::shared_ptr<CommandBufferAccessContext>;
John Zulauf64ffe552021-02-06 10:25:07 -070036class CommandExecutionContext;
John Zulaufd5115702021-01-18 12:34:33 -070037class ResourceAccessState;
John Zulauf4fa68462021-04-26 21:04:22 -060038struct ResourceFirstAccess;
John Zulaufd5115702021-01-18 12:34:33 -070039class SyncValidator;
John Zulauf355e49b2020-04-24 15:11:15 -060040
John Zulaufd0ec59f2021-03-13 14:25:08 -070041using ImageRangeEncoder = subresource_adapter::ImageRangeEncoder;
42using ImageRangeGen = subresource_adapter::ImageRangeGenerator;
43
John Zulauf2f952d22020-02-10 11:34:51 -070044enum SyncHazard {
45 NONE = 0,
46 READ_AFTER_WRITE,
47 WRITE_AFTER_READ,
48 WRITE_AFTER_WRITE,
49 READ_RACING_WRITE,
50 WRITE_RACING_WRITE,
51 WRITE_RACING_READ,
52};
John Zulauf9cb530d2019-09-30 14:14:10 -060053
John Zulauf8e3c3e92021-01-06 11:19:36 -070054enum class SyncOrdering : uint8_t {
55 kNonAttachment = 0,
56 kColorAttachment = 1,
57 kDepthStencilAttachment = 2,
58 kRaster = 3,
59 kNumOrderings = 4,
60};
61
John Zulauf9cb530d2019-09-30 14:14:10 -060062// Useful Utilites for manipulating StageAccess parameters, suitable as base class to save typing
63struct SyncStageAccess {
Jeremy Gebbend0de1f82020-11-09 08:21:07 -070064 static inline SyncStageAccessFlags FlagBit(SyncStageAccessIndex stage_access) {
John Zulauf9cb530d2019-09-30 14:14:10 -060065 return syncStageAccessInfoByStageAccessIndex[stage_access].stage_access_bit;
66 }
John Zulauf1507ee42020-05-18 11:33:09 -060067 static inline SyncStageAccessFlags Flags(SyncStageAccessIndex stage_access) {
68 return static_cast<SyncStageAccessFlags>(FlagBit(stage_access));
69 }
John Zulauf9cb530d2019-09-30 14:14:10 -060070
Jeremy Gebbend0de1f82020-11-09 08:21:07 -070071 static bool IsRead(const SyncStageAccessFlags &stage_access_bit) { return (stage_access_bit & syncStageAccessReadMask).any(); }
John Zulauf9cb530d2019-09-30 14:14:10 -060072 static bool IsRead(SyncStageAccessIndex stage_access_index) { return IsRead(FlagBit(stage_access_index)); }
73
Jeremy Gebbend0de1f82020-11-09 08:21:07 -070074 static bool IsWrite(const SyncStageAccessFlags &stage_access_bit) {
75 return (stage_access_bit & syncStageAccessWriteMask).any();
76 }
77 static bool HasWrite(const SyncStageAccessFlags &stage_access_mask) {
78 return (stage_access_mask & syncStageAccessWriteMask).any();
79 }
John Zulauf9cb530d2019-09-30 14:14:10 -060080 static bool IsWrite(SyncStageAccessIndex stage_access_index) { return IsWrite(FlagBit(stage_access_index)); }
Jeremy Gebben40a22942020-12-22 14:22:06 -070081 static VkPipelineStageFlags2KHR PipelineStageBit(SyncStageAccessIndex stage_access_index) {
John Zulauf9cb530d2019-09-30 14:14:10 -060082 return syncStageAccessInfoByStageAccessIndex[stage_access_index].stage_mask;
83 }
Jeremy Gebben40a22942020-12-22 14:22:06 -070084 static SyncStageAccessFlags AccessScopeByStage(VkPipelineStageFlags2KHR stages);
85 static SyncStageAccessFlags AccessScopeByAccess(VkAccessFlags2KHR access);
86 static SyncStageAccessFlags AccessScope(VkPipelineStageFlags2KHR stages, VkAccessFlags2KHR access);
87 static SyncStageAccessFlags AccessScope(const SyncStageAccessFlags &stage_scope, VkAccessFlags2KHR accesses) {
John Zulauf9cb530d2019-09-30 14:14:10 -060088 return stage_scope & AccessScopeByAccess(accesses);
89 }
90};
91
John Zulauf14940722021-04-12 15:19:02 -060092struct ResourceUsageRecord {
93 using TagIndex = size_t;
John Zulauffaea0ee2021-01-14 14:01:32 -070094 using Count = uint32_t;
John Zulauff4aecca2021-01-05 16:21:58 -070095 constexpr static TagIndex kMaxIndex = std::numeric_limits<TagIndex>::max();
John Zulauf3c2a0b32021-07-14 11:14:52 -060096 constexpr static Count kMaxCount = std::numeric_limits<Count>::max();
John Zulauffaea0ee2021-01-14 14:01:32 -070097 CMD_TYPE command = CMD_NONE;
98 Count seq_num = 0U;
99 Count sub_command = 0U;
John Zulauf3c2a0b32021-07-14 11:14:52 -0600100
101 // This is somewhat repetitive, but it prevents the need for Exec/Submit time touchup, after which usage records can be
102 // from different command buffers and resets.
John Zulauf4fa68462021-04-26 21:04:22 -0600103 const CMD_BUFFER_STATE *cb_state = nullptr; // plain pointer as a shared pointer is held by the context storing this record
John Zulauf3c2a0b32021-07-14 11:14:52 -0600104 Count reset_count;
Jeremy Gebben4bb73502020-12-14 11:17:50 -0700105
John Zulauf14940722021-04-12 15:19:02 -0600106 ResourceUsageRecord() = default;
John Zulauf3c2a0b32021-07-14 11:14:52 -0600107 ResourceUsageRecord(CMD_TYPE command_, Count seq_num_, Count sub_command_, const CMD_BUFFER_STATE *cb_state_,
108 Count reset_count_)
109 : command(command_), seq_num(seq_num_), sub_command(sub_command_), cb_state(cb_state_), reset_count(reset_count_) {}
John Zulauf5f13a792020-03-10 07:31:21 -0600110};
111
John Zulauf3c2a0b32021-07-14 11:14:52 -0600112// The resource tag index is relative to the command buffer or queue in which it's found
John Zulauf14940722021-04-12 15:19:02 -0600113using ResourceUsageTag = ResourceUsageRecord::TagIndex;
John Zulaufae842002021-04-15 18:20:55 -0600114using ResourceUsageRange = sparse_container::range<ResourceUsageTag>;
John Zulauf14940722021-04-12 15:19:02 -0600115
John Zulauf9cb530d2019-09-30 14:14:10 -0600116struct HazardResult {
John Zulauf59e25072020-07-17 10:55:21 -0600117 std::unique_ptr<const ResourceAccessState> access_state;
John Zulauf4fa68462021-04-26 21:04:22 -0600118 std::unique_ptr<const ResourceFirstAccess> recorded_access;
John Zulauf59e25072020-07-17 10:55:21 -0600119 SyncStageAccessIndex usage_index = std::numeric_limits<SyncStageAccessIndex>::max();
John Zulauf9cb530d2019-09-30 14:14:10 -0600120 SyncHazard hazard = NONE;
John Zulauf37ceaed2020-07-03 16:18:15 -0600121 SyncStageAccessFlags prior_access = 0U; // TODO -- change to a NONE enum in ...Bits
John Zulauf9cb530d2019-09-30 14:14:10 -0600122 ResourceUsageTag tag = ResourceUsageTag();
John Zulauf59e25072020-07-17 10:55:21 -0600123 void Set(const ResourceAccessState *access_state_, SyncStageAccessIndex usage_index_, SyncHazard hazard_,
John Zulauf14940722021-04-12 15:19:02 -0600124 const SyncStageAccessFlags &prior_, ResourceUsageTag tag_);
John Zulauf4fa68462021-04-26 21:04:22 -0600125 void AddRecordedAccess(const ResourceFirstAccess &first_access);
John Zulauf9cb530d2019-09-30 14:14:10 -0600126};
127
Jeremy Gebben9893daf2021-01-04 10:40:50 -0700128struct SyncExecScope {
Jeremy Gebben40a22942020-12-22 14:22:06 -0700129 VkPipelineStageFlags2KHR mask_param; // the xxxStageMask parameter passed by the caller
130 VkPipelineStageFlags2KHR
131 expanded_mask; // all stage bits covered by any 'catch all bits' in the parameter (eg. ALL_GRAPHICS_BIT).
132 VkPipelineStageFlags2KHR exec_scope; // all earlier or later stages that would be affected by a barrier using this scope.
Jeremy Gebben9893daf2021-01-04 10:40:50 -0700133 SyncStageAccessFlags valid_accesses; // all valid accesses that can be used with this scope.
134
135 SyncExecScope() : mask_param(0), expanded_mask(0), exec_scope(0), valid_accesses(0) {}
136
Jeremy Gebben40a22942020-12-22 14:22:06 -0700137 static SyncExecScope MakeSrc(VkQueueFlags queue_flags, VkPipelineStageFlags2KHR src_stage_mask);
138 static SyncExecScope MakeDst(VkQueueFlags queue_flags, VkPipelineStageFlags2KHR src_stage_mask);
Jeremy Gebben9893daf2021-01-04 10:40:50 -0700139};
140
John Zulauf3d84f1b2020-03-09 13:33:25 -0600141struct SyncBarrier {
John Zulaufc523bf62021-02-16 08:20:34 -0700142 SyncExecScope src_exec_scope;
John Zulauf3d84f1b2020-03-09 13:33:25 -0600143 SyncStageAccessFlags src_access_scope;
John Zulaufc523bf62021-02-16 08:20:34 -0700144 SyncExecScope dst_exec_scope;
John Zulauf3d84f1b2020-03-09 13:33:25 -0600145 SyncStageAccessFlags dst_access_scope;
146 SyncBarrier() = default;
Jeremy Gebben9893daf2021-01-04 10:40:50 -0700147 SyncBarrier(const SyncBarrier &other) = default;
John Zulauf3d84f1b2020-03-09 13:33:25 -0600148 SyncBarrier &operator=(const SyncBarrier &) = default;
Jeremy Gebben9893daf2021-01-04 10:40:50 -0700149
150 SyncBarrier(const SyncExecScope &src, const SyncExecScope &dst);
151
152 template <typename Barrier>
153 SyncBarrier(const Barrier &barrier, const SyncExecScope &src, const SyncExecScope &dst);
154
155 SyncBarrier(VkQueueFlags queue_flags, const VkSubpassDependency2 &barrier);
Jeremy Gebbendf3fcc32021-02-15 08:53:17 -0700156 // template constructor for sync2 barriers
157 template <typename Barrier>
158 SyncBarrier(VkQueueFlags queue_flags, const Barrier &barrier);
Jeremy Gebben9893daf2021-01-04 10:40:50 -0700159
John Zulaufa0a98292020-09-18 09:30:10 -0600160 void Merge(const SyncBarrier &other) {
John Zulaufc523bf62021-02-16 08:20:34 -0700161 // Note that after merge, only the exec_scope and access_scope fields are fully valid
162 // TODO: Do we need to update any of the other fields? Merging has limited application.
163 src_exec_scope.exec_scope |= other.src_exec_scope.exec_scope;
John Zulaufa0a98292020-09-18 09:30:10 -0600164 src_access_scope |= other.src_access_scope;
John Zulaufc523bf62021-02-16 08:20:34 -0700165 dst_exec_scope.exec_scope |= other.dst_exec_scope.exec_scope;
John Zulaufa0a98292020-09-18 09:30:10 -0600166 dst_access_scope |= other.dst_access_scope;
167 }
John Zulauf3d84f1b2020-03-09 13:33:25 -0600168};
John Zulauf69133422020-05-20 14:55:53 -0600169
John Zulauf43cc7462020-12-03 12:33:12 -0700170enum class AccessAddressType : uint32_t { kLinear = 0, kIdealized = 1, kMaxType = 1, kTypeCount = kMaxType + 1 };
171
John Zulauf4a6105a2020-11-17 15:11:05 -0700172struct SyncEventState {
John Zulauf4edde622021-02-15 08:54:50 -0700173 enum IgnoreReason { NotIgnored = 0, ResetWaitRace, Reset2WaitRace, SetRace, MissingStageBits, SetVsWait2 };
John Zulauf669dfd52021-01-27 17:15:28 -0700174 using EventPointer = std::shared_ptr<const EVENT_STATE>;
John Zulauf4a6105a2020-11-17 15:11:05 -0700175 using ScopeMap = sparse_container::range_map<VkDeviceSize, bool>;
176 EventPointer event;
177 CMD_TYPE last_command; // Only Event commands are valid here.
John Zulauf610e28c2021-08-03 17:46:23 -0600178 ResourceUsageTag last_command_tag; // Needed to filter replay validation
John Zulauf4a6105a2020-11-17 15:11:05 -0700179 CMD_TYPE unsynchronized_set;
Jeremy Gebben40a22942020-12-22 14:22:06 -0700180 VkPipelineStageFlags2KHR barriers;
Jeremy Gebben9893daf2021-01-04 10:40:50 -0700181 SyncExecScope scope;
John Zulauf4a6105a2020-11-17 15:11:05 -0700182 ResourceUsageTag first_scope_tag;
John Zulaufd5115702021-01-18 12:34:33 -0700183 bool destroyed;
John Zulauf4a6105a2020-11-17 15:11:05 -0700184 std::array<ScopeMap, static_cast<size_t>(AccessAddressType::kTypeCount)> first_scope;
John Zulauf669dfd52021-01-27 17:15:28 -0700185 template <typename EventPointerType>
186 SyncEventState(EventPointerType &&event_state)
187 : event(std::forward<EventPointerType>(event_state)),
John Zulaufd5115702021-01-18 12:34:33 -0700188 last_command(CMD_NONE),
John Zulauf610e28c2021-08-03 17:46:23 -0600189 last_command_tag(0),
John Zulaufd5115702021-01-18 12:34:33 -0700190 unsynchronized_set(CMD_NONE),
191 barriers(0U),
192 scope(),
193 first_scope_tag(),
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600194 destroyed((event_state.get() == nullptr) || event_state->Destroyed()) {}
John Zulauf4a6105a2020-11-17 15:11:05 -0700195 SyncEventState() : SyncEventState(EventPointer()) {}
196 void ResetFirstScope();
197 const ScopeMap &FirstScope(AccessAddressType address_type) const { return first_scope[static_cast<size_t>(address_type)]; }
John Zulauf4edde622021-02-15 08:54:50 -0700198 IgnoreReason IsIgnoredByWait(CMD_TYPE cmd, VkPipelineStageFlags2KHR srcStageMask) const;
Jeremy Gebben40a22942020-12-22 14:22:06 -0700199 bool HasBarrier(VkPipelineStageFlags2KHR stageMask, VkPipelineStageFlags2KHR exec_scope) const;
John Zulauf4a6105a2020-11-17 15:11:05 -0700200};
John Zulaufd5115702021-01-18 12:34:33 -0700201using SyncEventStateShared = std::shared_ptr<SyncEventState>;
202using SyncEventStateConstShared = std::shared_ptr<const SyncEventState>;
John Zulauf669dfd52021-01-27 17:15:28 -0700203class SyncEventsContext {
204 public:
Jeremy Gebbencbf22862021-03-03 12:01:22 -0700205 using Map = layer_data::unordered_map<const EVENT_STATE *, SyncEventStateShared>;
John Zulauf669dfd52021-01-27 17:15:28 -0700206 using iterator = Map::iterator;
207 using const_iterator = Map::const_iterator;
208
209 SyncEventState *GetFromShared(const SyncEventState::EventPointer &event_state) {
210 const auto find_it = map_.find(event_state.get());
211 if (find_it == map_.end()) {
John Zulauf6ce24372021-01-30 05:56:25 -0700212 if (!event_state.get()) return nullptr;
213
John Zulauf669dfd52021-01-27 17:15:28 -0700214 const auto *event_plain_ptr = event_state.get();
215 auto sync_state = SyncEventStateShared(new SyncEventState(event_state));
Jeremy Gebbencbf22862021-03-03 12:01:22 -0700216 auto insert_pair = map_.emplace(event_plain_ptr, sync_state);
John Zulauf669dfd52021-01-27 17:15:28 -0700217 return insert_pair.first->second.get();
218 }
219 return find_it->second.get();
220 }
221
222 const SyncEventState *Get(const EVENT_STATE *event_state) const {
223 const auto find_it = map_.find(event_state);
224 if (find_it == map_.end()) {
225 return nullptr;
226 }
227 return find_it->second.get();
228 }
John Zulauf6ce24372021-01-30 05:56:25 -0700229 const SyncEventState *Get(const SyncEventState::EventPointer &event_state) const { return Get(event_state.get()); }
John Zulauf669dfd52021-01-27 17:15:28 -0700230
John Zulauf8eda1562021-04-13 17:06:41 -0600231 void ApplyBarrier(const SyncExecScope &src, const SyncExecScope &dst);
232
John Zulauf669dfd52021-01-27 17:15:28 -0700233 // stl style naming for range-for support
234 inline iterator begin() { return map_.begin(); }
235 inline const_iterator begin() const { return map_.begin(); }
236 inline iterator end() { return map_.end(); }
237 inline const_iterator end() const { return map_.end(); }
238
239 void Destroy(const EVENT_STATE *event_state) {
240 auto sync_it = map_.find(event_state);
241 if (sync_it != map_.end()) {
242 sync_it->second->destroyed = true;
243 map_.erase(sync_it);
244 }
245 }
246 void Clear() { map_.clear(); }
247
248 private:
249 Map map_;
250};
John Zulauf4a6105a2020-11-17 15:11:05 -0700251
John Zulauf4fa68462021-04-26 21:04:22 -0600252struct ResourceFirstAccess {
253 ResourceUsageTag tag;
254 SyncStageAccessIndex usage_index;
255 SyncOrdering ordering_rule;
256 ResourceFirstAccess(ResourceUsageTag tag_, SyncStageAccessIndex usage_index_, SyncOrdering ordering_rule_)
257 : tag(tag_), usage_index(usage_index_), ordering_rule(ordering_rule_){};
258 ResourceFirstAccess(const ResourceFirstAccess &other) = default;
259 ResourceFirstAccess(ResourceFirstAccess &&other) = default;
260 ResourceFirstAccess &operator=(const ResourceFirstAccess &rhs) = default;
261 ResourceFirstAccess &operator=(ResourceFirstAccess &&rhs) = default;
262 bool operator==(const ResourceFirstAccess &rhs) const {
263 return (tag == rhs.tag) && (usage_index == rhs.usage_index) && (ordering_rule == rhs.ordering_rule);
264 }
265};
John Zulauf3d84f1b2020-03-09 13:33:25 -0600266
John Zulauf9cb530d2019-09-30 14:14:10 -0600267class ResourceAccessState : public SyncStageAccess {
268 protected:
John Zulauf8e3c3e92021-01-06 11:19:36 -0700269 struct OrderingBarrier {
Jeremy Gebben40a22942020-12-22 14:22:06 -0700270 VkPipelineStageFlags2KHR exec_scope;
John Zulauf8e3c3e92021-01-06 11:19:36 -0700271 SyncStageAccessFlags access_scope;
272 OrderingBarrier() = default;
Jeremy Gebben40a22942020-12-22 14:22:06 -0700273 OrderingBarrier(VkPipelineStageFlags2KHR es, SyncStageAccessFlags as) : exec_scope(es), access_scope(as) {}
John Zulauf8e3c3e92021-01-06 11:19:36 -0700274 OrderingBarrier &operator=(const OrderingBarrier &) = default;
John Zulauf4fa68462021-04-26 21:04:22 -0600275 OrderingBarrier &operator|=(const OrderingBarrier &rhs) {
276 exec_scope |= rhs.exec_scope;
277 access_scope |= rhs.access_scope;
278 return *this;
John Zulauffaea0ee2021-01-14 14:01:32 -0700279 }
280 };
John Zulauf4fa68462021-04-26 21:04:22 -0600281 using OrderingBarriers = std::array<OrderingBarrier, static_cast<size_t>(SyncOrdering::kNumOrderings)>;
282 using FirstAccesses = small_vector<ResourceFirstAccess, 3>;
John Zulauffaea0ee2021-01-14 14:01:32 -0700283
John Zulauf9cb530d2019-09-30 14:14:10 -0600284 // Mutliple read operations can be simlutaneously (and independently) synchronized,
285 // given the only the second execution scope creates a dependency chain, we have to track each,
286 // but only up to one per pipeline stage (as another read from the *same* stage become more recent,
287 // and applicable one for hazard detection
288 struct ReadState {
Jeremy Gebben40a22942020-12-22 14:22:06 -0700289 VkPipelineStageFlags2KHR stage; // The stage of this read
John Zulauf37ceaed2020-07-03 16:18:15 -0600290 SyncStageAccessFlags access; // TODO: Change to FlagBits when we have a None bit enum
John Zulauff51fbb62020-10-02 14:43:24 -0600291 // TODO: Revisit whether this needs to support multiple reads per stage
Jeremy Gebben40a22942020-12-22 14:22:06 -0700292 VkPipelineStageFlags2KHR barriers; // all applicable barriered stages
John Zulauf9cb530d2019-09-30 14:14:10 -0600293 ResourceUsageTag tag;
Jeremy Gebben40a22942020-12-22 14:22:06 -0700294 VkPipelineStageFlags2KHR pending_dep_chain; // Should be zero except during barrier application
295 // Excluded from comparison
John Zulauf89311b42020-09-29 16:28:47 -0600296 ReadState() = default;
Jeremy Gebben40a22942020-12-22 14:22:06 -0700297 ReadState(VkPipelineStageFlags2KHR stage_, SyncStageAccessFlags access_, VkPipelineStageFlags2KHR barriers_,
John Zulauf14940722021-04-12 15:19:02 -0600298 ResourceUsageTag tag_)
John Zulaufab7756b2020-12-29 16:10:16 -0700299 : stage(stage_), access(access_), barriers(barriers_), tag(tag_), pending_dep_chain(0) {}
John Zulaufe5da6e52020-03-18 15:32:18 -0600300 bool operator==(const ReadState &rhs) const {
John Zulauf37ceaed2020-07-03 16:18:15 -0600301 bool same = (stage == rhs.stage) && (access == rhs.access) && (barriers == rhs.barriers) && (tag == rhs.tag);
John Zulaufe5da6e52020-03-18 15:32:18 -0600302 return same;
303 }
Jeremy Gebben40a22942020-12-22 14:22:06 -0700304 bool IsReadBarrierHazard(VkPipelineStageFlags2KHR src_exec_scope) const {
John Zulauf4a6105a2020-11-17 15:11:05 -0700305 // If the read stage is not in the src sync scope
306 // *AND* not execution chained with an existing sync barrier (that's the or)
307 // then the barrier access is unsafe (R/W after R)
308 return (src_exec_scope & (stage | barriers)) == 0;
309 }
310
John Zulaufe5da6e52020-03-18 15:32:18 -0600311 bool operator!=(const ReadState &rhs) const { return !(*this == rhs); }
Jeremy Gebben40a22942020-12-22 14:22:06 -0700312 inline void Set(VkPipelineStageFlags2KHR stage_, const SyncStageAccessFlags &access_, VkPipelineStageFlags2KHR barriers_,
John Zulauf14940722021-04-12 15:19:02 -0600313 ResourceUsageTag tag_) {
John Zulauf4285ee92020-09-23 10:20:52 -0600314 stage = stage_;
315 access = access_;
316 barriers = barriers_;
317 tag = tag_;
John Zulauf89311b42020-09-29 16:28:47 -0600318 pending_dep_chain = 0; // If this is a new read, we aren't applying a barrier set.
John Zulauf4285ee92020-09-23 10:20:52 -0600319 }
John Zulauf9cb530d2019-09-30 14:14:10 -0600320 };
321
322 public:
323 HazardResult DetectHazard(SyncStageAccessIndex usage_index) const;
John Zulauf4fa68462021-04-26 21:04:22 -0600324 HazardResult DetectHazard(SyncStageAccessIndex usage_index, SyncOrdering ordering_rule) const;
325 HazardResult DetectHazard(SyncStageAccessIndex usage_index, const OrderingBarrier &ordering) const;
John Zulaufae842002021-04-15 18:20:55 -0600326 HazardResult DetectHazard(const ResourceAccessState &recorded_use, const ResourceUsageRange &tag_range) const;
327
328 HazardResult DetectAsyncHazard(SyncStageAccessIndex usage_index, ResourceUsageTag start_tag) const;
329 HazardResult DetectAsyncHazard(const ResourceAccessState &recorded_use, const ResourceUsageRange &tag_range,
330 ResourceUsageTag start_tag) const;
John Zulauf3d84f1b2020-03-09 13:33:25 -0600331
Jeremy Gebben40a22942020-12-22 14:22:06 -0700332 HazardResult DetectBarrierHazard(SyncStageAccessIndex usage_index, VkPipelineStageFlags2KHR source_exec_scope,
Jeremy Gebbend0de1f82020-11-09 08:21:07 -0700333 const SyncStageAccessFlags &source_access_scope) const;
Jeremy Gebben40a22942020-12-22 14:22:06 -0700334 HazardResult DetectBarrierHazard(SyncStageAccessIndex usage_index, VkPipelineStageFlags2KHR source_exec_scope,
John Zulauf14940722021-04-12 15:19:02 -0600335 const SyncStageAccessFlags &source_access_scope, ResourceUsageTag event_tag) const;
John Zulauf3d84f1b2020-03-09 13:33:25 -0600336
John Zulauf14940722021-04-12 15:19:02 -0600337 void Update(SyncStageAccessIndex usage_index, SyncOrdering ordering_rule, ResourceUsageTag tag);
338 void SetWrite(const SyncStageAccessFlags &usage_bit, ResourceUsageTag tag);
John Zulauf5f13a792020-03-10 07:31:21 -0600339 void Resolve(const ResourceAccessState &other);
John Zulaufb02c1eb2020-10-06 16:33:36 -0600340 void ApplyBarriers(const std::vector<SyncBarrier> &barriers, bool layout_transition);
John Zulauf14940722021-04-12 15:19:02 -0600341 void ApplyBarriers(const std::vector<SyncBarrier> &barriers, ResourceUsageTag tag);
John Zulauf89311b42020-09-29 16:28:47 -0600342 void ApplyBarrier(const SyncBarrier &barrier, bool layout_transition);
John Zulauf14940722021-04-12 15:19:02 -0600343 void ApplyBarrier(ResourceUsageTag scope_tag, const SyncBarrier &barrier, bool layout_transition);
344 void ApplyPendingBarriers(ResourceUsageTag tag);
John Zulaufae842002021-04-15 18:20:55 -0600345 bool FirstAccessInTagRange(const ResourceUsageRange &tag_range) const;
John Zulauf9cb530d2019-09-30 14:14:10 -0600346
John Zulauf4fa68462021-04-26 21:04:22 -0600347 void OffsetTag(ResourceUsageTag offset) {
348 if (last_write.any()) write_tag += offset;
349 for (auto &read_access : last_reads) {
350 read_access.tag += offset;
351 }
352 for (auto &first : first_accesses_) {
353 first.tag += offset;
354 }
355 }
John Zulauf9cb530d2019-09-30 14:14:10 -0600356 ResourceAccessState()
John Zulauf355e49b2020-04-24 15:11:15 -0600357 : write_barriers(~SyncStageAccessFlags(0)),
358 write_dependency_chain(0),
John Zulauf355e49b2020-04-24 15:11:15 -0600359 write_tag(),
John Zulaufd14743a2020-07-03 09:42:39 -0600360 last_write(0),
John Zulauff51fbb62020-10-02 14:43:24 -0600361 input_attachment_read(false),
John Zulauf361fb532020-07-22 10:45:39 -0600362 last_read_stages(0),
John Zulauf89311b42020-09-29 16:28:47 -0600363 read_execution_barriers(0),
364 pending_write_dep_chain(0),
365 pending_layout_transition(false),
John Zulauffaea0ee2021-01-14 14:01:32 -0700366 pending_write_barriers(0),
John Zulauf4fa68462021-04-26 21:04:22 -0600367 pending_layout_ordering_(),
John Zulauffaea0ee2021-01-14 14:01:32 -0700368 first_accesses_(),
John Zulauf4fa68462021-04-26 21:04:22 -0600369 first_read_stages_(0U),
370 first_write_layout_ordering_() {}
John Zulauf9cb530d2019-09-30 14:14:10 -0600371
John Zulaufb02c1eb2020-10-06 16:33:36 -0600372 bool HasPendingState() const {
Jeremy Gebbend0de1f82020-11-09 08:21:07 -0700373 return (0 != pending_layout_transition) || pending_write_barriers.any() || (0 != pending_write_dep_chain);
John Zulaufb02c1eb2020-10-06 16:33:36 -0600374 }
John Zulauf3d84f1b2020-03-09 13:33:25 -0600375 bool HasWriteOp() const { return last_write != 0; }
John Zulaufe5da6e52020-03-18 15:32:18 -0600376 bool operator==(const ResourceAccessState &rhs) const {
377 bool same = (write_barriers == rhs.write_barriers) && (write_dependency_chain == rhs.write_dependency_chain) &&
John Zulaufab7756b2020-12-29 16:10:16 -0700378 (last_reads == rhs.last_reads) && (last_read_stages == rhs.last_read_stages) && (write_tag == rhs.write_tag) &&
379 (input_attachment_read == rhs.input_attachment_read) &&
John Zulauffaea0ee2021-01-14 14:01:32 -0700380 (read_execution_barriers == rhs.read_execution_barriers) && (first_accesses_ == rhs.first_accesses_);
John Zulaufe5da6e52020-03-18 15:32:18 -0600381 return same;
382 }
383 bool operator!=(const ResourceAccessState &rhs) const { return !(*this == rhs); }
Jeremy Gebben40a22942020-12-22 14:22:06 -0700384 VkPipelineStageFlags2KHR GetReadBarriers(const SyncStageAccessFlags &usage) const;
John Zulauf59e25072020-07-17 10:55:21 -0600385 SyncStageAccessFlags GetWriteBarriers() const { return write_barriers; }
Jeremy Gebben40a22942020-12-22 14:22:06 -0700386 bool InSourceScopeOrChain(VkPipelineStageFlags2KHR src_exec_scope, SyncStageAccessFlags src_access_scope) const {
John Zulauf4a6105a2020-11-17 15:11:05 -0700387 return ReadInSourceScopeOrChain(src_exec_scope) || WriteInSourceScopeOrChain(src_exec_scope, src_access_scope);
388 }
John Zulauf3d84f1b2020-03-09 13:33:25 -0600389
John Zulauf9cb530d2019-09-30 14:14:10 -0600390 private:
Jeremy Gebben40a22942020-12-22 14:22:06 -0700391 static constexpr VkPipelineStageFlags2KHR kInvalidAttachmentStage = ~VkPipelineStageFlags2KHR(0);
Jeremy Gebbend0de1f82020-11-09 08:21:07 -0700392 bool IsWriteHazard(SyncStageAccessFlags usage) const { return (usage & ~write_barriers).any(); }
Jeremy Gebben40a22942020-12-22 14:22:06 -0700393 bool IsRAWHazard(VkPipelineStageFlags2KHR usage_stage, const SyncStageAccessFlags &usage) const;
394 bool IsWriteBarrierHazard(VkPipelineStageFlags2KHR src_exec_scope, const SyncStageAccessFlags &src_access_scope) const {
John Zulauf6b583642021-10-05 17:25:31 -0600395 // If the previous write is *not* a layout transition
396 // *AND* is *not* in the 1st access scope
John Zulauf4a6105a2020-11-17 15:11:05 -0700397 // *AND* the current barrier is not in the dependency chain
398 // *AND* the there is no prior memory barrier for the previous write in the dependency chain
399 // then the barrier access is unsafe (R/W after W)
John Zulauf6b583642021-10-05 17:25:31 -0600400 return (last_write != SYNC_IMAGE_LAYOUT_TRANSITION_BIT) && (last_write & src_access_scope).none() &&
401 (((src_exec_scope & write_dependency_chain) == 0) || (write_barriers & src_access_scope).none());
John Zulauf4a6105a2020-11-17 15:11:05 -0700402 }
Jeremy Gebben40a22942020-12-22 14:22:06 -0700403 bool ReadInSourceScopeOrChain(VkPipelineStageFlags2KHR src_exec_scope) const {
John Zulauf4a6105a2020-11-17 15:11:05 -0700404 return (0 != (src_exec_scope & (last_read_stages | read_execution_barriers)));
405 }
Jeremy Gebben40a22942020-12-22 14:22:06 -0700406 bool WriteInSourceScopeOrChain(VkPipelineStageFlags2KHR src_exec_scope, SyncStageAccessFlags src_access_scope) const {
Jeremy Gebbend0de1f82020-11-09 08:21:07 -0700407 return (src_access_scope & last_write).any() || (write_dependency_chain & src_exec_scope);
John Zulaufa0a98292020-09-18 09:30:10 -0600408 }
John Zulaufd14743a2020-07-03 09:42:39 -0600409
Jeremy Gebben40a22942020-12-22 14:22:06 -0700410 static bool IsReadHazard(VkPipelineStageFlags2KHR stage_mask, const VkPipelineStageFlags2KHR barriers) {
John Zulaufd14743a2020-07-03 09:42:39 -0600411 return stage_mask != (stage_mask & barriers);
412 }
413
Jeremy Gebben40a22942020-12-22 14:22:06 -0700414 bool IsReadHazard(VkPipelineStageFlags2KHR stage_mask, const ReadState &read_access) const {
John Zulaufd14743a2020-07-03 09:42:39 -0600415 return IsReadHazard(stage_mask, read_access.barriers);
John Zulauf0cb5be22020-01-23 12:18:22 -0700416 }
Jeremy Gebben40a22942020-12-22 14:22:06 -0700417 VkPipelineStageFlags2KHR GetOrderedStages(const OrderingBarrier &ordering) const;
John Zulauf8e3c3e92021-01-06 11:19:36 -0700418
John Zulauf14940722021-04-12 15:19:02 -0600419 void UpdateFirst(ResourceUsageTag tag, SyncStageAccessIndex usage_index, SyncOrdering ordering_rule);
John Zulauf4fa68462021-04-26 21:04:22 -0600420 void TouchupFirstForLayoutTransition(ResourceUsageTag tag, const OrderingBarrier &layout_ordering);
John Zulauffaea0ee2021-01-14 14:01:32 -0700421
John Zulauf8e3c3e92021-01-06 11:19:36 -0700422 static const OrderingBarrier &GetOrderingRules(SyncOrdering ordering_enum) {
423 return kOrderingRules[static_cast<size_t>(ordering_enum)];
424 }
John Zulaufd14743a2020-07-03 09:42:39 -0600425
Jeremy Gebbend0de1f82020-11-09 08:21:07 -0700426 // TODO: Add a NONE (zero) enum to SyncStageAccessFlags for input_attachment_read and last_write
John Zulaufd14743a2020-07-03 09:42:39 -0600427
John Zulauf9cb530d2019-09-30 14:14:10 -0600428 // With reads, each must be "safe" relative to it's prior write, so we need only
429 // save the most recent write operation (as anything *transitively* unsafe would arleady
430 // be included
431 SyncStageAccessFlags write_barriers; // union of applicable barrier masks since last write
Jeremy Gebben40a22942020-12-22 14:22:06 -0700432 VkPipelineStageFlags2KHR write_dependency_chain; // intiially zero, but accumulating the dstStages of barriers if they chain.
John Zulauf9cb530d2019-09-30 14:14:10 -0600433 ResourceUsageTag write_tag;
John Zulauf355e49b2020-04-24 15:11:15 -0600434 SyncStageAccessFlags last_write; // only the most recent write
John Zulauf9cb530d2019-09-30 14:14:10 -0600435
John Zulauff51fbb62020-10-02 14:43:24 -0600436 // TODO Input Attachment cleanup for multiple reads in a given stage
437 // Tracks whether the fragment shader read is input attachment read
438 bool input_attachment_read;
John Zulaufd14743a2020-07-03 09:42:39 -0600439
Jeremy Gebben40a22942020-12-22 14:22:06 -0700440 VkPipelineStageFlags2KHR last_read_stages;
441 VkPipelineStageFlags2KHR read_execution_barriers;
Artem Bolgar09b01542021-06-01 23:49:14 -0700442 small_vector<ReadState, 3, uint32_t> last_reads;
John Zulauf89311b42020-09-29 16:28:47 -0600443
444 // Pending execution state to support independent parallel barriers
Jeremy Gebben40a22942020-12-22 14:22:06 -0700445 VkPipelineStageFlags2KHR pending_write_dep_chain;
John Zulauf89311b42020-09-29 16:28:47 -0600446 bool pending_layout_transition;
447 SyncStageAccessFlags pending_write_barriers;
John Zulauf4fa68462021-04-26 21:04:22 -0600448 OrderingBarrier pending_layout_ordering_;
John Zulauffaea0ee2021-01-14 14:01:32 -0700449 FirstAccesses first_accesses_;
Jeremy Gebben40a22942020-12-22 14:22:06 -0700450 VkPipelineStageFlags2KHR first_read_stages_;
John Zulauf4fa68462021-04-26 21:04:22 -0600451 OrderingBarrier first_write_layout_ordering_;
John Zulauf8e3c3e92021-01-06 11:19:36 -0700452
453 static OrderingBarriers kOrderingRules;
John Zulauf9cb530d2019-09-30 14:14:10 -0600454};
John Zulauf22aefed2021-03-11 18:14:35 -0700455using ResourceAccessStateFunction = std::function<void(ResourceAccessState *)>;
456using ResourceAccessStateConstFunction = std::function<void(const ResourceAccessState &)>;
John Zulauf9cb530d2019-09-30 14:14:10 -0600457
John Zulauf16adfc92020-04-08 10:28:33 -0600458using ResourceAccessRangeMap = sparse_container::range_map<VkDeviceSize, ResourceAccessState>;
John Zulauf5c5e88d2019-12-26 11:22:02 -0700459using ResourceAccessRange = typename ResourceAccessRangeMap::key_type;
John Zulauf22aefed2021-03-11 18:14:35 -0700460using ResourceAccessRangeIndex = typename ResourceAccessRange::index_type;
John Zulauf355e49b2020-04-24 15:11:15 -0600461using ResourceRangeMergeIterator = sparse_container::parallel_iterator<ResourceAccessRangeMap, const ResourceAccessRangeMap>;
John Zulauf9cb530d2019-09-30 14:14:10 -0600462
John Zulaufd0ec59f2021-03-13 14:25:08 -0700463class AttachmentViewGen {
464 public:
465 enum Gen { kViewSubresource = 0, kRenderArea = 1, kDepthOnlyRenderArea = 2, kStencilOnlyRenderArea = 3, kGenSize = 4 };
466 AttachmentViewGen(const IMAGE_VIEW_STATE *view_, const VkOffset3D &offset, const VkExtent3D &extent);
467 AttachmentViewGen(const AttachmentViewGen &other) = default;
468 AttachmentViewGen(AttachmentViewGen &&other) = default;
469 AccessAddressType GetAddressType() const;
470 const IMAGE_VIEW_STATE *GetViewState() const { return view_; }
471 const ImageRangeGen *GetRangeGen(Gen type) const;
472 bool IsValid() const { return gen_store_[Gen::kViewSubresource]; }
473 Gen GetDepthStencilRenderAreaGenType(bool depth_op, bool stencil_op) const;
474
475 private:
476 using RangeGenStore = layer_data::optional<ImageRangeGen>;
477 const IMAGE_VIEW_STATE *view_ = nullptr;
478 VkImageAspectFlags view_mask_ = 0U;
479 std::array<RangeGenStore, Gen::kGenSize> gen_store_;
480};
481
482using AttachmentViewGenVector = std::vector<AttachmentViewGen>;
483
John Zulaufe7f6a5e2021-01-16 14:31:18 -0700484using SyncMemoryBarrier = SyncBarrier;
485struct SyncBufferMemoryBarrier {
486 using Buffer = std::shared_ptr<const BUFFER_STATE>;
487 Buffer buffer;
488 SyncBarrier barrier;
489 ResourceAccessRange range;
John Zulaufd5115702021-01-18 12:34:33 -0700490 bool IsLayoutTransition() const { return false; }
491 const ResourceAccessRange &Range() const { return range; };
492 const BUFFER_STATE *GetState() const { return buffer.get(); }
John Zulaufe7f6a5e2021-01-16 14:31:18 -0700493 SyncBufferMemoryBarrier(const Buffer &buffer_, const SyncBarrier &barrier_, const ResourceAccessRange &range_)
494 : buffer(buffer_), barrier(barrier_), range(range_) {}
495 SyncBufferMemoryBarrier() = default;
496};
497
498struct SyncImageMemoryBarrier {
499 using Image = std::shared_ptr<const IMAGE_STATE>;
John Zulauf110413c2021-03-20 05:38:38 -0600500
John Zulaufe7f6a5e2021-01-16 14:31:18 -0700501 Image image;
502 uint32_t index;
503 SyncBarrier barrier;
504 VkImageLayout old_layout;
505 VkImageLayout new_layout;
John Zulauf110413c2021-03-20 05:38:38 -0600506 VkImageSubresourceRange range;
John Zulaufd5115702021-01-18 12:34:33 -0700507
508 bool IsLayoutTransition() const { return old_layout != new_layout; }
John Zulauf110413c2021-03-20 05:38:38 -0600509 const VkImageSubresourceRange &Range() const { return range; };
John Zulaufd5115702021-01-18 12:34:33 -0700510 const IMAGE_STATE *GetState() const { return image.get(); }
John Zulaufe7f6a5e2021-01-16 14:31:18 -0700511 SyncImageMemoryBarrier(const Image &image_, uint32_t index_, const SyncBarrier &barrier_, VkImageLayout old_layout_,
512 VkImageLayout new_layout_, const VkImageSubresourceRange &subresource_range_)
513 : image(image_),
514 index(index_),
515 barrier(barrier_),
516 old_layout(old_layout_),
517 new_layout(new_layout_),
John Zulauf110413c2021-03-20 05:38:38 -0600518 range(subresource_range_) {}
John Zulaufe7f6a5e2021-01-16 14:31:18 -0700519 SyncImageMemoryBarrier() = default;
520};
521
522class SyncOpBase {
523 public:
sfricke-samsung85584a72021-09-30 21:43:38 -0700524 SyncOpBase() : cmd_(CMD_NONE) {}
525 SyncOpBase(CMD_TYPE cmd) : cmd_(cmd) {}
John Zulauf8eda1562021-04-13 17:06:41 -0600526 virtual ~SyncOpBase() = default;
527
sfricke-samsung85584a72021-09-30 21:43:38 -0700528 const char *CmdName() const { return CommandTypeString(cmd_); }
John Zulaufe7f6a5e2021-01-16 14:31:18 -0700529 virtual bool Validate(const CommandBufferAccessContext &cb_context) const = 0;
John Zulauf8eda1562021-04-13 17:06:41 -0600530 virtual ResourceUsageTag Record(CommandBufferAccessContext *cb_context) const = 0;
531 virtual bool ReplayValidate(ResourceUsageTag recorded_tag, const CommandBufferAccessContext &recorded_context,
John Zulauf610e28c2021-08-03 17:46:23 -0600532 ResourceUsageTag base_tag, CommandBufferAccessContext *active_context) const = 0;
John Zulauf4fa68462021-04-26 21:04:22 -0600533 virtual void DoRecord(ResourceUsageTag tag, AccessContext *access_context, SyncEventsContext *events_context) const = 0;
John Zulauf36ef9282021-02-02 11:47:24 -0700534
535 protected:
536 CMD_TYPE cmd_;
John Zulaufe7f6a5e2021-01-16 14:31:18 -0700537};
538
John Zulaufd5115702021-01-18 12:34:33 -0700539class SyncOpBarriers : public SyncOpBase {
540 protected:
541 template <typename Barriers, typename FunctorFactory>
John Zulauf14940722021-04-12 15:19:02 -0600542 static void ApplyBarriers(const Barriers &barriers, const FunctorFactory &factory, ResourceUsageTag tag,
John Zulaufd5115702021-01-18 12:34:33 -0700543 AccessContext *context);
544 template <typename Barriers, typename FunctorFactory>
John Zulauf14940722021-04-12 15:19:02 -0600545 static void ApplyGlobalBarriers(const Barriers &barriers, const FunctorFactory &factory, ResourceUsageTag tag,
John Zulaufd5115702021-01-18 12:34:33 -0700546 AccessContext *access_context);
John Zulaufe7f6a5e2021-01-16 14:31:18 -0700547
John Zulauf36ef9282021-02-02 11:47:24 -0700548 SyncOpBarriers(CMD_TYPE cmd, const SyncValidator &sync_state, VkQueueFlags queue_flags, VkPipelineStageFlags srcStageMask,
John Zulaufd5115702021-01-18 12:34:33 -0700549 VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount,
550 const VkMemoryBarrier *pMemoryBarriers, uint32_t bufferMemoryBarrierCount,
551 const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
552 const VkImageMemoryBarrier *pImageMemoryBarriers);
John Zulauf4edde622021-02-15 08:54:50 -0700553 SyncOpBarriers(CMD_TYPE cmd, const SyncValidator &sync_state, VkQueueFlags queue_flags, uint32_t event_count,
554 const VkDependencyInfoKHR *pDependencyInfo);
John Zulaufe7f6a5e2021-01-16 14:31:18 -0700555
John Zulauf8eda1562021-04-13 17:06:41 -0600556 ~SyncOpBarriers() override = default;
557
John Zulaufe7f6a5e2021-01-16 14:31:18 -0700558 protected:
John Zulauf4edde622021-02-15 08:54:50 -0700559 struct BarrierSet {
560 VkDependencyFlags dependency_flags;
561 SyncExecScope src_exec_scope;
562 SyncExecScope dst_exec_scope;
563 std::vector<SyncMemoryBarrier> memory_barriers;
564 std::vector<SyncBufferMemoryBarrier> buffer_memory_barriers;
565 std::vector<SyncImageMemoryBarrier> image_memory_barriers;
566 bool single_exec_scope;
567 void MakeMemoryBarriers(const SyncExecScope &src, const SyncExecScope &dst, VkDependencyFlags dependencyFlags,
568 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers);
569 void MakeBufferMemoryBarriers(const SyncValidator &sync_state, const SyncExecScope &src, const SyncExecScope &dst,
570 VkDependencyFlags dependencyFlags, uint32_t bufferMemoryBarrierCount,
571 const VkBufferMemoryBarrier *pBufferMemoryBarriers);
572 void MakeImageMemoryBarriers(const SyncValidator &sync_state, const SyncExecScope &src, const SyncExecScope &dst,
573 VkDependencyFlags dependencyFlags, uint32_t imageMemoryBarrierCount,
574 const VkImageMemoryBarrier *pImageMemoryBarriers);
575 void MakeMemoryBarriers(VkQueueFlags queue_flags, VkDependencyFlags dependency_flags, uint32_t barrier_count,
576 const VkMemoryBarrier2KHR *barriers);
577 void MakeBufferMemoryBarriers(const SyncValidator &sync_state, VkQueueFlags queue_flags, VkDependencyFlags dependency_flags,
578 uint32_t barrier_count, const VkBufferMemoryBarrier2KHR *barriers);
579 void MakeImageMemoryBarriers(const SyncValidator &sync_state, VkQueueFlags queue_flags, VkDependencyFlags dependency_flags,
580 uint32_t barrier_count, const VkImageMemoryBarrier2KHR *barriers);
581 };
582 std::vector<BarrierSet> barriers_;
John Zulaufe7f6a5e2021-01-16 14:31:18 -0700583};
584
John Zulaufd5115702021-01-18 12:34:33 -0700585class SyncOpPipelineBarrier : public SyncOpBarriers {
586 public:
John Zulauf36ef9282021-02-02 11:47:24 -0700587 SyncOpPipelineBarrier(CMD_TYPE cmd, const SyncValidator &sync_state, VkQueueFlags queue_flags,
588 VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags,
589 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, uint32_t bufferMemoryBarrierCount,
John Zulaufd5115702021-01-18 12:34:33 -0700590 const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
591 const VkImageMemoryBarrier *pImageMemoryBarriers);
Jeremy Gebbendf3fcc32021-02-15 08:53:17 -0700592 SyncOpPipelineBarrier(CMD_TYPE cmd, const SyncValidator &sync_state, VkQueueFlags queue_flags,
593 const VkDependencyInfoKHR &pDependencyInfo);
John Zulauf8eda1562021-04-13 17:06:41 -0600594 ~SyncOpPipelineBarrier() override = default;
595
John Zulaufd5115702021-01-18 12:34:33 -0700596 bool Validate(const CommandBufferAccessContext &cb_context) const override;
John Zulauf8eda1562021-04-13 17:06:41 -0600597 ResourceUsageTag Record(CommandBufferAccessContext *cb_context) const override;
598 bool ReplayValidate(ResourceUsageTag recorded_tag, const CommandBufferAccessContext &recorded_context,
John Zulauf610e28c2021-08-03 17:46:23 -0600599 ResourceUsageTag base_tag, CommandBufferAccessContext *active_context) const override;
John Zulauf4fa68462021-04-26 21:04:22 -0600600 void DoRecord(ResourceUsageTag recorded_tag, AccessContext *access_context, SyncEventsContext *events_context) const override;
John Zulaufd5115702021-01-18 12:34:33 -0700601};
602
603class SyncOpWaitEvents : public SyncOpBarriers {
604 public:
John Zulauf36ef9282021-02-02 11:47:24 -0700605 SyncOpWaitEvents(CMD_TYPE cmd, const SyncValidator &sync_state, VkQueueFlags queue_flags, uint32_t eventCount,
606 const VkEvent *pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
607 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, uint32_t bufferMemoryBarrierCount,
John Zulaufd5115702021-01-18 12:34:33 -0700608 const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
609 const VkImageMemoryBarrier *pImageMemoryBarriers);
John Zulauf4edde622021-02-15 08:54:50 -0700610
611 SyncOpWaitEvents(CMD_TYPE cmd, const SyncValidator &sync_state, VkQueueFlags queue_flags, uint32_t eventCount,
612 const VkEvent *pEvents, const VkDependencyInfoKHR *pDependencyInfo);
John Zulauf8eda1562021-04-13 17:06:41 -0600613 ~SyncOpWaitEvents() override = default;
John Zulauf4edde622021-02-15 08:54:50 -0700614
John Zulaufd5115702021-01-18 12:34:33 -0700615 bool Validate(const CommandBufferAccessContext &cb_context) const override;
John Zulauf8eda1562021-04-13 17:06:41 -0600616 ResourceUsageTag Record(CommandBufferAccessContext *cb_context) const override;
617 bool ReplayValidate(ResourceUsageTag recorded_tag, const CommandBufferAccessContext &recorded_context,
John Zulauf610e28c2021-08-03 17:46:23 -0600618 ResourceUsageTag base_tag, CommandBufferAccessContext *active_context) const override;
John Zulauf4fa68462021-04-26 21:04:22 -0600619 void DoRecord(ResourceUsageTag recorded_tag, AccessContext *access_context, SyncEventsContext *events_context) const override;
John Zulaufd5115702021-01-18 12:34:33 -0700620
621 protected:
John Zulauf610e28c2021-08-03 17:46:23 -0600622 static const char *const kIgnored;
623 bool DoValidate(const CommandBufferAccessContext &cb_context, const ResourceUsageTag base_tag) const;
John Zulaufd5115702021-01-18 12:34:33 -0700624 // TODO PHASE2 This is the wrong thing to use for "replay".. as the event state will have moved on since the record
625 // TODO PHASE2 May need to capture by value w.r.t. "first use" or build up in calling/enqueue context through replay.
John Zulauf669dfd52021-01-27 17:15:28 -0700626 std::vector<std::shared_ptr<const EVENT_STATE>> events_;
627 void MakeEventsList(const SyncValidator &sync_state, uint32_t event_count, const VkEvent *events);
John Zulaufd5115702021-01-18 12:34:33 -0700628};
629
John Zulauf6ce24372021-01-30 05:56:25 -0700630class SyncOpResetEvent : public SyncOpBase {
631 public:
John Zulauf36ef9282021-02-02 11:47:24 -0700632 SyncOpResetEvent(CMD_TYPE cmd, const SyncValidator &sync_state, VkQueueFlags queue_flags, VkEvent event,
John Zulauf4edde622021-02-15 08:54:50 -0700633 VkPipelineStageFlags2KHR stageMask);
John Zulauf8eda1562021-04-13 17:06:41 -0600634 ~SyncOpResetEvent() override = default;
635
John Zulauf6ce24372021-01-30 05:56:25 -0700636 bool Validate(const CommandBufferAccessContext &cb_context) const override;
John Zulauf8eda1562021-04-13 17:06:41 -0600637 ResourceUsageTag Record(CommandBufferAccessContext *cb_context) const override;
638 bool ReplayValidate(ResourceUsageTag recorded_tag, const CommandBufferAccessContext &recorded_context,
John Zulauf610e28c2021-08-03 17:46:23 -0600639 ResourceUsageTag base_tag, CommandBufferAccessContext *active_context) const override;
John Zulauf4fa68462021-04-26 21:04:22 -0600640 void DoRecord(ResourceUsageTag recorded_tag, AccessContext *access_context, SyncEventsContext *events_context) const override;
John Zulauf6ce24372021-01-30 05:56:25 -0700641
642 private:
John Zulauf1bf30522021-09-03 15:39:06 -0600643 bool DoValidate(const CommandBufferAccessContext& cb_context, const ResourceUsageTag base_tag) const;
John Zulauf6ce24372021-01-30 05:56:25 -0700644 std::shared_ptr<const EVENT_STATE> event_;
645 SyncExecScope exec_scope_;
646};
647
648class SyncOpSetEvent : public SyncOpBase {
649 public:
John Zulauf36ef9282021-02-02 11:47:24 -0700650 SyncOpSetEvent(CMD_TYPE cmd, const SyncValidator &sync_state, VkQueueFlags queue_flags, VkEvent event,
John Zulauf4edde622021-02-15 08:54:50 -0700651 VkPipelineStageFlags2KHR stageMask);
652 SyncOpSetEvent(CMD_TYPE cmd, const SyncValidator &sync_state, VkQueueFlags queue_flags, VkEvent event,
653 const VkDependencyInfoKHR &dep_info);
John Zulauf8eda1562021-04-13 17:06:41 -0600654 ~SyncOpSetEvent() override = default;
655
John Zulauf6ce24372021-01-30 05:56:25 -0700656 bool Validate(const CommandBufferAccessContext &cb_context) const override;
John Zulauf8eda1562021-04-13 17:06:41 -0600657 ResourceUsageTag Record(CommandBufferAccessContext *cb_context) const override;
658 bool ReplayValidate(ResourceUsageTag recorded_tag, const CommandBufferAccessContext &recorded_context,
John Zulauf610e28c2021-08-03 17:46:23 -0600659 ResourceUsageTag base_tag, CommandBufferAccessContext *active_context) const override;
John Zulauf6ce24372021-01-30 05:56:25 -0700660
661 private:
John Zulauf610e28c2021-08-03 17:46:23 -0600662 bool DoValidate(const CommandBufferAccessContext &cb_context, const ResourceUsageTag base_tag) const;
663 void DoRecord(ResourceUsageTag recorded_tag, AccessContext *access_context, SyncEventsContext *events_context) const override;
John Zulauf6ce24372021-01-30 05:56:25 -0700664 std::shared_ptr<const EVENT_STATE> event_;
665 SyncExecScope src_exec_scope_;
John Zulauf4edde622021-02-15 08:54:50 -0700666 // Note that the dep info is *not* dehandled, but retained for comparison with a future WaitEvents2
667 std::shared_ptr<safe_VkDependencyInfoKHR> dep_info_;
John Zulauf6ce24372021-01-30 05:56:25 -0700668};
John Zulauf64ffe552021-02-06 10:25:07 -0700669
670class SyncOpBeginRenderPass : public SyncOpBase {
671 public:
672 SyncOpBeginRenderPass(CMD_TYPE cmd, const SyncValidator &sync_state, const VkRenderPassBeginInfo *pRenderPassBegin,
sfricke-samsung85584a72021-09-30 21:43:38 -0700673 const VkSubpassBeginInfo *pSubpassBeginInfo);
John Zulauf8eda1562021-04-13 17:06:41 -0600674 ~SyncOpBeginRenderPass() override = default;
675
John Zulauf64ffe552021-02-06 10:25:07 -0700676 bool Validate(const CommandBufferAccessContext &cb_context) const override;
John Zulauf8eda1562021-04-13 17:06:41 -0600677 ResourceUsageTag Record(CommandBufferAccessContext *cb_context) const override;
678 bool ReplayValidate(ResourceUsageTag recorded_tag, const CommandBufferAccessContext &recorded_context,
John Zulauf610e28c2021-08-03 17:46:23 -0600679 ResourceUsageTag base_tag, CommandBufferAccessContext *active_context) const override;
John Zulauf4fa68462021-04-26 21:04:22 -0600680 void DoRecord(ResourceUsageTag recorded_tag, AccessContext *access_context, SyncEventsContext *events_context) const override;
John Zulauf64ffe552021-02-06 10:25:07 -0700681
682 protected:
683 safe_VkRenderPassBeginInfo renderpass_begin_info_;
684 safe_VkSubpassBeginInfo subpass_begin_info_;
685 std::vector<std::shared_ptr<const IMAGE_VIEW_STATE>> shared_attachments_;
686 std::vector<const IMAGE_VIEW_STATE *> attachments_;
687 std::shared_ptr<const RENDER_PASS_STATE> rp_state_;
688};
689
690class SyncOpNextSubpass : public SyncOpBase {
691 public:
692 SyncOpNextSubpass(CMD_TYPE cmd, const SyncValidator &sync_state, const VkSubpassBeginInfo *pSubpassBeginInfo,
sfricke-samsung85584a72021-09-30 21:43:38 -0700693 const VkSubpassEndInfo *pSubpassEndInfo);
John Zulauf8eda1562021-04-13 17:06:41 -0600694 ~SyncOpNextSubpass() override = default;
695
John Zulauf64ffe552021-02-06 10:25:07 -0700696 bool Validate(const CommandBufferAccessContext &cb_context) const override;
John Zulauf8eda1562021-04-13 17:06:41 -0600697 ResourceUsageTag Record(CommandBufferAccessContext *cb_context) const override;
698 bool ReplayValidate(ResourceUsageTag recorded_tag, const CommandBufferAccessContext &recorded_context,
John Zulauf610e28c2021-08-03 17:46:23 -0600699 ResourceUsageTag base_tag, CommandBufferAccessContext *active_context) const override;
John Zulauf4fa68462021-04-26 21:04:22 -0600700 void DoRecord(ResourceUsageTag recorded_tag, AccessContext *access_context, SyncEventsContext *events_context) const override;
John Zulauf64ffe552021-02-06 10:25:07 -0700701
702 protected:
703 safe_VkSubpassBeginInfo subpass_begin_info_;
704 safe_VkSubpassEndInfo subpass_end_info_;
705};
706
707class SyncOpEndRenderPass : public SyncOpBase {
708 public:
sfricke-samsung85584a72021-09-30 21:43:38 -0700709 SyncOpEndRenderPass(CMD_TYPE cmd, const SyncValidator &sync_state, const VkSubpassEndInfo *pSubpassEndInfo);
John Zulauf8eda1562021-04-13 17:06:41 -0600710 ~SyncOpEndRenderPass() override = default;
711
John Zulauf64ffe552021-02-06 10:25:07 -0700712 bool Validate(const CommandBufferAccessContext &cb_context) const override;
John Zulauf8eda1562021-04-13 17:06:41 -0600713 ResourceUsageTag Record(CommandBufferAccessContext *cb_context) const override;
714 bool ReplayValidate(ResourceUsageTag recorded_tag, const CommandBufferAccessContext &recorded_context,
John Zulauf610e28c2021-08-03 17:46:23 -0600715 ResourceUsageTag base_tag, CommandBufferAccessContext *active_context) const override;
John Zulauf4fa68462021-04-26 21:04:22 -0600716 void DoRecord(ResourceUsageTag recorded_tag, AccessContext *access_context, SyncEventsContext *events_context) const override;
John Zulauf64ffe552021-02-06 10:25:07 -0700717
718 protected:
719 safe_VkSubpassEndInfo subpass_end_info_;
720};
721
John Zulauf540266b2020-04-06 18:54:53 -0600722class AccessContext {
John Zulauf5c5e88d2019-12-26 11:22:02 -0700723 public:
John Zulauf69133422020-05-20 14:55:53 -0600724 enum DetectOptions : uint32_t {
John Zulauf355e49b2020-04-24 15:11:15 -0600725 kDetectPrevious = 1U << 0,
726 kDetectAsync = 1U << 1,
727 kDetectAll = (kDetectPrevious | kDetectAsync)
John Zulauf16adfc92020-04-08 10:28:33 -0600728 };
John Zulauf43cc7462020-12-03 12:33:12 -0700729 using MapArray = std::array<ResourceAccessRangeMap, static_cast<size_t>(AccessAddressType::kTypeCount)>;
John Zulauf16adfc92020-04-08 10:28:33 -0600730
John Zulauf3d84f1b2020-03-09 13:33:25 -0600731 struct TrackBack {
John Zulaufa0a98292020-09-18 09:30:10 -0600732 std::vector<SyncBarrier> barriers;
John Zulauf1a224292020-06-30 14:52:13 -0600733 const AccessContext *context;
John Zulaufbaea94f2020-09-15 17:55:16 -0600734 TrackBack(const AccessContext *context_, VkQueueFlags queue_flags_,
John Zulaufa0a98292020-09-18 09:30:10 -0600735 const std::vector<const VkSubpassDependency2 *> &subpass_dependencies_)
736 : barriers(), context(context_) {
737 barriers.reserve(subpass_dependencies_.size());
738 for (const VkSubpassDependency2 *dependency : subpass_dependencies_) {
739 assert(dependency);
740 barriers.emplace_back(queue_flags_, *dependency);
741 }
742 }
John Zulauf3d84f1b2020-03-09 13:33:25 -0600743 TrackBack &operator=(const TrackBack &) = default;
744 TrackBack() = default;
745 };
John Zulauf5c5e88d2019-12-26 11:22:02 -0700746
John Zulauf355e49b2020-04-24 15:11:15 -0600747 HazardResult DetectHazard(const BUFFER_STATE &buffer, SyncStageAccessIndex usage_index, const ResourceAccessRange &range) const;
John Zulauf540266b2020-04-06 18:54:53 -0600748 HazardResult DetectHazard(const IMAGE_STATE &image, SyncStageAccessIndex current_usage,
John Zulauf3d84f1b2020-03-09 13:33:25 -0600749 const VkImageSubresourceLayers &subresource, const VkOffset3D &offset,
750 const VkExtent3D &extent) const;
John Zulauf69133422020-05-20 14:55:53 -0600751 template <typename Detector>
John Zulaufd0ec59f2021-03-13 14:25:08 -0700752 HazardResult DetectHazard(Detector &detector, const AttachmentViewGen &view_gen, AttachmentViewGen::Gen gen_type,
753 DetectOptions options) const;
754 template <typename Detector>
John Zulauf69133422020-05-20 14:55:53 -0600755 HazardResult DetectHazard(Detector &detector, const IMAGE_STATE &image, const VkImageSubresourceRange &subresource_range,
756 const VkOffset3D &offset, const VkExtent3D &extent, DetectOptions options) const;
John Zulauf110413c2021-03-20 05:38:38 -0600757 template <typename Detector>
758 HazardResult DetectHazard(Detector &detector, const IMAGE_STATE &image, const VkImageSubresourceRange &subresource_range,
759 DetectOptions options) const;
John Zulauf1507ee42020-05-18 11:33:09 -0600760 HazardResult DetectHazard(const IMAGE_STATE &image, SyncStageAccessIndex current_usage,
John Zulauf110413c2021-03-20 05:38:38 -0600761 const VkImageSubresourceRange &subresource_range) const;
John Zulaufd0ec59f2021-03-13 14:25:08 -0700762 HazardResult DetectHazard(const AttachmentViewGen &view_gen, AttachmentViewGen::Gen gen_type,
763 SyncStageAccessIndex current_usage, SyncOrdering ordering_rule) const;
764
John Zulauf69133422020-05-20 14:55:53 -0600765 HazardResult DetectHazard(const IMAGE_STATE &image, SyncStageAccessIndex current_usage,
John Zulauf8e3c3e92021-01-06 11:19:36 -0700766 const VkImageSubresourceRange &subresource_range, SyncOrdering ordering_rule,
John Zulauf69133422020-05-20 14:55:53 -0600767 const VkOffset3D &offset, const VkExtent3D &extent) const;
Jeremy Gebben40a22942020-12-22 14:22:06 -0700768 HazardResult DetectImageBarrierHazard(const IMAGE_STATE &image, VkPipelineStageFlags2KHR src_exec_scope,
Jeremy Gebbend0de1f82020-11-09 08:21:07 -0700769 const SyncStageAccessFlags &src_access_scope,
John Zulauf4a6105a2020-11-17 15:11:05 -0700770 const VkImageSubresourceRange &subresource_range, const SyncEventState &sync_event,
771 DetectOptions options) const;
John Zulaufd0ec59f2021-03-13 14:25:08 -0700772 HazardResult DetectImageBarrierHazard(const AttachmentViewGen &attachment_view, const SyncBarrier &barrier,
773 DetectOptions options) const;
Jeremy Gebben40a22942020-12-22 14:22:06 -0700774 HazardResult DetectImageBarrierHazard(const IMAGE_STATE &image, VkPipelineStageFlags2KHR src_exec_scope,
John Zulauf4a6105a2020-11-17 15:11:05 -0700775 const SyncStageAccessFlags &src_access_scope,
Jeremy Gebbend0de1f82020-11-09 08:21:07 -0700776 const VkImageSubresourceRange &subresource_range, DetectOptions options) const;
Jeremy Gebben40a22942020-12-22 14:22:06 -0700777 HazardResult DetectImageBarrierHazard(const IMAGE_STATE &image, VkPipelineStageFlags2KHR src_exec_scope,
Jeremy Gebbend0de1f82020-11-09 08:21:07 -0700778 const SyncStageAccessFlags &src_stage_accesses,
779 const VkImageMemoryBarrier &barrier) const;
John Zulaufe7f6a5e2021-01-16 14:31:18 -0700780 HazardResult DetectImageBarrierHazard(const SyncImageMemoryBarrier &image_barrier) const;
John Zulaufd0ec59f2021-03-13 14:25:08 -0700781 HazardResult DetectSubpassTransitionHazard(const TrackBack &track_back, const AttachmentViewGen &attach_view) const;
John Zulauf3d84f1b2020-03-09 13:33:25 -0600782
John Zulaufb02c1eb2020-10-06 16:33:36 -0600783 void RecordLayoutTransitions(const RENDER_PASS_STATE &rp_state, uint32_t subpass,
John Zulauf14940722021-04-12 15:19:02 -0600784 const AttachmentViewGenVector &attachment_views, ResourceUsageTag tag);
John Zulaufb02c1eb2020-10-06 16:33:36 -0600785
John Zulaufae842002021-04-15 18:20:55 -0600786 HazardResult DetectFirstUseHazard(const ResourceUsageRange &tag_range, const AccessContext &access_context) const;
787
John Zulaufe5da6e52020-03-18 15:32:18 -0600788 const TrackBack &GetDstExternalTrackBack() const { return dst_external_; }
John Zulauf3d84f1b2020-03-09 13:33:25 -0600789 void Reset() {
John Zulauf3d84f1b2020-03-09 13:33:25 -0600790 prev_.clear();
John Zulauf355e49b2020-04-24 15:11:15 -0600791 prev_by_subpass_.clear();
John Zulauf3d84f1b2020-03-09 13:33:25 -0600792 async_.clear();
John Zulauf22aefed2021-03-11 18:14:35 -0700793 src_external_ = nullptr;
John Zulaufa0a98292020-09-18 09:30:10 -0600794 dst_external_ = TrackBack();
Jeremy Gebbenc4b78c52020-12-11 09:39:47 -0700795 start_tag_ = ResourceUsageTag();
John Zulauf16adfc92020-04-08 10:28:33 -0600796 for (auto &map : access_state_maps_) {
797 map.clear();
798 }
John Zulauf3d84f1b2020-03-09 13:33:25 -0600799 }
John Zulaufb02c1eb2020-10-06 16:33:36 -0600800
801 // Follow the context previous to access the access state, supporting "lazy" import into the context. Not intended for
802 // subpass layout transition, as the pending state handling is more complex
John Zulauf5f13a792020-03-10 07:31:21 -0600803 // TODO: See if returning the lower_bound would be useful from a performance POV -- look at the lower_bound overhead
804 // Would need to add a "hint" overload to parallel_iterator::invalidate_[AB] call, if so.
John Zulauf22aefed2021-03-11 18:14:35 -0700805 template <typename BarrierAction>
806 void ResolvePreviousAccessStack(AccessAddressType type, const ResourceAccessRange &range, ResourceAccessRangeMap *descent_map,
807 const ResourceAccessState *infill_state, const BarrierAction &previous_barrie) const;
John Zulauf43cc7462020-12-03 12:33:12 -0700808 void ResolvePreviousAccess(AccessAddressType type, const ResourceAccessRange &range, ResourceAccessRangeMap *descent_map,
John Zulauf22aefed2021-03-11 18:14:35 -0700809 const ResourceAccessState *infill_state,
810 const ResourceAccessStateFunction *previous_barrier = nullptr) const;
John Zulauf4a6105a2020-11-17 15:11:05 -0700811 void ResolvePreviousAccesses();
John Zulaufb02c1eb2020-10-06 16:33:36 -0600812 template <typename BarrierAction>
John Zulaufd0ec59f2021-03-13 14:25:08 -0700813 void ResolveAccessRange(const AttachmentViewGen &view_gen, AttachmentViewGen::Gen gen_type, BarrierAction &barrier_action,
814 ResourceAccessRangeMap *descent_map, const ResourceAccessState *infill_state) const;
John Zulaufb02c1eb2020-10-06 16:33:36 -0600815 template <typename BarrierAction>
John Zulauf43cc7462020-12-03 12:33:12 -0700816 void ResolveAccessRange(AccessAddressType type, const ResourceAccessRange &range, BarrierAction &barrier_action,
John Zulauf355e49b2020-04-24 15:11:15 -0600817 ResourceAccessRangeMap *resolve_map, const ResourceAccessState *infill_state,
818 bool recur_to_infill = true) const;
John Zulaufb02c1eb2020-10-06 16:33:36 -0600819
John Zulauf8e3c3e92021-01-06 11:19:36 -0700820 void UpdateAccessState(const BUFFER_STATE &buffer, SyncStageAccessIndex current_usage, SyncOrdering ordering_rule,
John Zulauf14940722021-04-12 15:19:02 -0600821 const ResourceAccessRange &range, ResourceUsageTag tag);
John Zulauf8e3c3e92021-01-06 11:19:36 -0700822 void UpdateAccessState(const IMAGE_STATE &image, SyncStageAccessIndex current_usage, SyncOrdering ordering_rule,
John Zulauf110413c2021-03-20 05:38:38 -0600823 const VkImageSubresourceRange &subresource_range, const ResourceUsageTag &tag);
824 void UpdateAccessState(const IMAGE_STATE &image, SyncStageAccessIndex current_usage, SyncOrdering ordering_rule,
John Zulauf355e49b2020-04-24 15:11:15 -0600825 const VkImageSubresourceRange &subresource_range, const VkOffset3D &offset, const VkExtent3D &extent,
John Zulauf14940722021-04-12 15:19:02 -0600826 ResourceUsageTag tag);
John Zulaufd0ec59f2021-03-13 14:25:08 -0700827 void UpdateAccessState(const AttachmentViewGen &view_gen, AttachmentViewGen::Gen gen_type, SyncStageAccessIndex current_usage,
John Zulauf14940722021-04-12 15:19:02 -0600828 SyncOrdering ordering_rule, ResourceUsageTag tag);
John Zulauf8e3c3e92021-01-06 11:19:36 -0700829 void UpdateAccessState(const IMAGE_STATE &image, SyncStageAccessIndex current_usage, SyncOrdering ordering_rule,
John Zulauf3d84f1b2020-03-09 13:33:25 -0600830 const VkImageSubresourceLayers &subresource, const VkOffset3D &offset, const VkExtent3D &extent,
John Zulauf14940722021-04-12 15:19:02 -0600831 ResourceUsageTag tag);
John Zulaufd0ec59f2021-03-13 14:25:08 -0700832 void UpdateAttachmentResolveAccess(const RENDER_PASS_STATE &rp_state, const AttachmentViewGenVector &attachment_views,
John Zulauf14940722021-04-12 15:19:02 -0600833 uint32_t subpass, ResourceUsageTag tag);
John Zulaufd0ec59f2021-03-13 14:25:08 -0700834 void UpdateAttachmentStoreAccess(const RENDER_PASS_STATE &rp_state, const AttachmentViewGenVector &attachment_views,
John Zulauf14940722021-04-12 15:19:02 -0600835 uint32_t subpass, ResourceUsageTag tag);
John Zulauf3d84f1b2020-03-09 13:33:25 -0600836
John Zulauf540266b2020-04-06 18:54:53 -0600837 void ResolveChildContexts(const std::vector<AccessContext> &contexts);
John Zulauf3d84f1b2020-03-09 13:33:25 -0600838
John Zulauf4fa68462021-04-26 21:04:22 -0600839 void ImportAsyncContexts(const AccessContext &from);
John Zulaufd0ec59f2021-03-13 14:25:08 -0700840 template <typename Action, typename RangeGen>
841 void ApplyUpdateAction(AccessAddressType address_type, const Action &action, RangeGen *range_gen_arg);
John Zulauf540266b2020-04-06 18:54:53 -0600842 template <typename Action>
John Zulaufd0ec59f2021-03-13 14:25:08 -0700843 void ApplyUpdateAction(const AttachmentViewGen &view_gen, AttachmentViewGen::Gen gen_type, const Action &action);
John Zulauf540266b2020-04-06 18:54:53 -0600844 template <typename Action>
John Zulaufd5115702021-01-18 12:34:33 -0700845 void ApplyToContext(const Action &barrier_action);
John Zulauf43cc7462020-12-03 12:33:12 -0700846 static AccessAddressType ImageAddressType(const IMAGE_STATE &image);
John Zulauf16adfc92020-04-08 10:28:33 -0600847
John Zulauf540266b2020-04-06 18:54:53 -0600848 AccessContext(uint32_t subpass, VkQueueFlags queue_flags, const std::vector<SubpassDependencyGraphNode> &dependencies,
John Zulauf1a224292020-06-30 14:52:13 -0600849 const std::vector<AccessContext> &contexts, const AccessContext *external_context);
John Zulauf540266b2020-04-06 18:54:53 -0600850
851 AccessContext() { Reset(); }
John Zulauf7635de32020-05-29 17:14:15 -0600852 AccessContext(const AccessContext &copy_from) = default;
John Zulauf3d84f1b2020-03-09 13:33:25 -0600853
John Zulauf43cc7462020-12-03 12:33:12 -0700854 ResourceAccessRangeMap &GetAccessStateMap(AccessAddressType type) { return access_state_maps_[static_cast<size_t>(type)]; }
855 const ResourceAccessRangeMap &GetAccessStateMap(AccessAddressType type) const {
856 return access_state_maps_[static_cast<size_t>(type)];
857 }
858 ResourceAccessRangeMap &GetLinearMap() { return GetAccessStateMap(AccessAddressType::kLinear); }
859 const ResourceAccessRangeMap &GetLinearMap() const { return GetAccessStateMap(AccessAddressType::kLinear); }
860 ResourceAccessRangeMap &GetIdealizedMap() { return GetAccessStateMap(AccessAddressType::kIdealized); }
861 const ResourceAccessRangeMap &GetIdealizedMap() const { return GetAccessStateMap(AccessAddressType::kIdealized); }
John Zulauf355e49b2020-04-24 15:11:15 -0600862 const TrackBack *GetTrackBackFromSubpass(uint32_t subpass) const {
863 if (subpass == VK_SUBPASS_EXTERNAL) {
John Zulauf22aefed2021-03-11 18:14:35 -0700864 return src_external_;
John Zulauf355e49b2020-04-24 15:11:15 -0600865 } else {
866 assert(subpass < prev_by_subpass_.size());
867 return prev_by_subpass_[subpass];
868 }
869 }
John Zulauf16adfc92020-04-08 10:28:33 -0600870
John Zulauf64ffe552021-02-06 10:25:07 -0700871 bool ValidateLayoutTransitions(const CommandExecutionContext &ex_context, const RENDER_PASS_STATE &rp_state,
John Zulaufd0ec59f2021-03-13 14:25:08 -0700872 const VkRect2D &render_area, uint32_t subpass, const AttachmentViewGenVector &attachment_views,
873 const char *func_name) const;
John Zulauf64ffe552021-02-06 10:25:07 -0700874 bool ValidateLoadOperation(const CommandExecutionContext &ex_context, const RENDER_PASS_STATE &rp_state,
John Zulaufd0ec59f2021-03-13 14:25:08 -0700875 const VkRect2D &render_area, uint32_t subpass, const AttachmentViewGenVector &attachment_views,
876 const char *func_name) const;
877 bool ValidateStoreOperation(const CommandExecutionContext &ex_context,
878
879 const RENDER_PASS_STATE &rp_state,
880
881 const VkRect2D &render_area, uint32_t subpass, const AttachmentViewGenVector &attachment_views,
882 const char *func_name) const;
John Zulauf64ffe552021-02-06 10:25:07 -0700883 bool ValidateResolveOperations(const CommandExecutionContext &ex_context, const RENDER_PASS_STATE &rp_state,
John Zulaufd0ec59f2021-03-13 14:25:08 -0700884 const VkRect2D &render_area, const AttachmentViewGenVector &attachment_views,
John Zulauffaea0ee2021-01-14 14:01:32 -0700885 const char *func_name, uint32_t subpass) const;
John Zulauf1507ee42020-05-18 11:33:09 -0600886
John Zulauf14940722021-04-12 15:19:02 -0600887 void SetStartTag(ResourceUsageTag tag) { start_tag_ = tag; }
John Zulauf4a6105a2020-11-17 15:11:05 -0700888 template <typename Action>
889 void ForAll(Action &&action);
Jeremy Gebbenc4b78c52020-12-11 09:39:47 -0700890
John Zulauf3d84f1b2020-03-09 13:33:25 -0600891 private:
892 template <typename Detector>
John Zulauf43cc7462020-12-03 12:33:12 -0700893 HazardResult DetectHazard(AccessAddressType type, const Detector &detector, const ResourceAccessRange &range,
John Zulauf355e49b2020-04-24 15:11:15 -0600894 DetectOptions options) const;
John Zulauf3d84f1b2020-03-09 13:33:25 -0600895 template <typename Detector>
John Zulauf43cc7462020-12-03 12:33:12 -0700896 HazardResult DetectAsyncHazard(AccessAddressType type, const Detector &detector, const ResourceAccessRange &range) const;
John Zulauf5f13a792020-03-10 07:31:21 -0600897 template <typename Detector>
John Zulauf43cc7462020-12-03 12:33:12 -0700898 HazardResult DetectPreviousHazard(AccessAddressType type, const Detector &detector, const ResourceAccessRange &range) const;
John Zulauf8e3c3e92021-01-06 11:19:36 -0700899 void UpdateAccessState(AccessAddressType type, SyncStageAccessIndex current_usage, SyncOrdering ordering_rule,
John Zulauf14940722021-04-12 15:19:02 -0600900 const ResourceAccessRange &range, ResourceUsageTag tag);
John Zulaufb02c1eb2020-10-06 16:33:36 -0600901
902 MapArray access_state_maps_;
John Zulauf3d84f1b2020-03-09 13:33:25 -0600903 std::vector<TrackBack> prev_;
John Zulauf355e49b2020-04-24 15:11:15 -0600904 std::vector<TrackBack *> prev_by_subpass_;
Jeremy Gebbenc4b78c52020-12-11 09:39:47 -0700905 std::vector<const AccessContext *> async_;
John Zulauf22aefed2021-03-11 18:14:35 -0700906 TrackBack *src_external_;
John Zulaufe5da6e52020-03-18 15:32:18 -0600907 TrackBack dst_external_;
Jeremy Gebbenc4b78c52020-12-11 09:39:47 -0700908 ResourceUsageTag start_tag_;
John Zulauf3d84f1b2020-03-09 13:33:25 -0600909};
910
John Zulauf355e49b2020-04-24 15:11:15 -0600911class RenderPassAccessContext {
912 public:
John Zulaufd0ec59f2021-03-13 14:25:08 -0700913 static AttachmentViewGenVector CreateAttachmentViewGen(const VkRect2D &render_area,
914 const std::vector<const IMAGE_VIEW_STATE *> &attachment_views);
John Zulauf64ffe552021-02-06 10:25:07 -0700915 RenderPassAccessContext() : rp_state_(nullptr), render_area_(VkRect2D()), current_subpass_(0) {}
916 RenderPassAccessContext(const RENDER_PASS_STATE &rp_state, const VkRect2D &render_area, VkQueueFlags queue_flags,
917 const std::vector<const IMAGE_VIEW_STATE *> &attachment_views, const AccessContext *external_context);
John Zulauf355e49b2020-04-24 15:11:15 -0600918
John Zulauf64ffe552021-02-06 10:25:07 -0700919 bool ValidateDrawSubpassAttachment(const CommandExecutionContext &ex_context, const CMD_BUFFER_STATE &cmd,
920 const char *func_name) const;
John Zulauf14940722021-04-12 15:19:02 -0600921 void RecordDrawSubpassAttachment(const CMD_BUFFER_STATE &cmd, ResourceUsageTag tag);
John Zulauf64ffe552021-02-06 10:25:07 -0700922 bool ValidateNextSubpass(const CommandExecutionContext &ex_context, const char *command_name) const;
923 bool ValidateEndRenderPass(const CommandExecutionContext &ex_context, const char *func_name) const;
924 bool ValidateFinalSubpassLayoutTransitions(const CommandExecutionContext &ex_context, const char *func_name) const;
John Zulauf355e49b2020-04-24 15:11:15 -0600925
John Zulauf14940722021-04-12 15:19:02 -0600926 void RecordLayoutTransitions(ResourceUsageTag tag);
927 void RecordLoadOperations(ResourceUsageTag tag);
928 void RecordBeginRenderPass(ResourceUsageTag tag);
929 void RecordNextSubpass(ResourceUsageTag prev_subpass_tag, ResourceUsageTag next_subpass_tag);
930 void RecordEndRenderPass(AccessContext *external_context, ResourceUsageTag tag);
John Zulauf355e49b2020-04-24 15:11:15 -0600931
John Zulauf540266b2020-04-06 18:54:53 -0600932 AccessContext &CurrentContext() { return subpass_contexts_[current_subpass_]; }
933 const AccessContext &CurrentContext() const { return subpass_contexts_[current_subpass_]; }
John Zulauf355e49b2020-04-24 15:11:15 -0600934 const std::vector<AccessContext> &GetContexts() const { return subpass_contexts_; }
935 uint32_t GetCurrentSubpass() const { return current_subpass_; }
936 const RENDER_PASS_STATE *GetRenderPassState() const { return rp_state_; }
John Zulauf64ffe552021-02-06 10:25:07 -0700937 AccessContext *CreateStoreResolveProxy() const;
John Zulauf355e49b2020-04-24 15:11:15 -0600938
939 private:
John Zulauf355e49b2020-04-24 15:11:15 -0600940 const RENDER_PASS_STATE *rp_state_;
John Zulauf64ffe552021-02-06 10:25:07 -0700941 const VkRect2D render_area_;
John Zulauf355e49b2020-04-24 15:11:15 -0600942 uint32_t current_subpass_;
943 std::vector<AccessContext> subpass_contexts_;
John Zulaufd0ec59f2021-03-13 14:25:08 -0700944 AttachmentViewGenVector attachment_views_;
John Zulauf3d84f1b2020-03-09 13:33:25 -0600945};
946
John Zulauf64ffe552021-02-06 10:25:07 -0700947// Command execution context is the base class for command buffer and queue contexts
948// Preventing unintented leakage of subclass specific state, storing enough information
949// for message logging.
950// TODO: determine where to draw the design split for tag tracking (is there anything command to Queues and CB's)
951class CommandExecutionContext {
John Zulauf3d84f1b2020-03-09 13:33:25 -0600952 public:
John Zulauf64ffe552021-02-06 10:25:07 -0700953 CommandExecutionContext() : sync_state_(nullptr) {}
954 CommandExecutionContext(SyncValidator *sync_validator) : sync_state_(sync_validator) {}
955 virtual ~CommandExecutionContext() = default;
956 const SyncValidator &GetSyncState() const {
957 assert(sync_state_);
958 return *sync_state_;
959 }
960 SyncValidator &GetSyncState() {
961 assert(sync_state_);
962 return *sync_state_;
963 }
John Zulauf4fa68462021-04-26 21:04:22 -0600964 virtual std::string FormatUsage(ResourceUsageTag tag) const = 0;
965 virtual std::string FormatUsage(const ResourceFirstAccess &access) const = 0;
John Zulauf64ffe552021-02-06 10:25:07 -0700966 virtual std::string FormatUsage(const HazardResult &hazard) const = 0;
967
968 protected:
969 SyncValidator *sync_state_;
970};
971
972class CommandBufferAccessContext : public CommandExecutionContext {
973 public:
John Zulauf8eda1562021-04-13 17:06:41 -0600974 using SyncOpPointer = std::shared_ptr<SyncOpBase>;
975 struct SyncOpEntry {
976 ResourceUsageTag tag;
977 SyncOpPointer sync_op;
978 SyncOpEntry(ResourceUsageTag tag_, SyncOpPointer &&sync_op_) : tag(tag_), sync_op(std::move(sync_op_)) {}
979 SyncOpEntry() = default;
980 SyncOpEntry(const SyncOpEntry &other) = default;
981 };
982
John Zulauf64ffe552021-02-06 10:25:07 -0700983 CommandBufferAccessContext(SyncValidator *sync_validator = nullptr)
984 : CommandExecutionContext(sync_validator),
John Zulauf4fa68462021-04-26 21:04:22 -0600985 cb_state_(),
986 queue_flags_(),
987 destroyed_(false),
John Zulauf14940722021-04-12 15:19:02 -0600988 access_log_(),
John Zulauf3c2a0b32021-07-14 11:14:52 -0600989 cbs_referenced_(),
John Zulauffaea0ee2021-01-14 14:01:32 -0700990 command_number_(0),
991 subcommand_number_(0),
John Zulauf355e49b2020-04-24 15:11:15 -0600992 reset_count_(0),
John Zulauf355e49b2020-04-24 15:11:15 -0600993 cb_access_context_(),
994 current_context_(&cb_access_context_),
John Zulauf669dfd52021-01-27 17:15:28 -0700995 events_context_(),
John Zulauf4fa68462021-04-26 21:04:22 -0600996 render_pass_contexts_(),
997 current_renderpass_context_(),
998 sync_ops_() {}
John Zulauf355e49b2020-04-24 15:11:15 -0600999 CommandBufferAccessContext(SyncValidator &sync_validator, std::shared_ptr<CMD_BUFFER_STATE> &cb_state, VkQueueFlags queue_flags)
John Zulauf64ffe552021-02-06 10:25:07 -07001000 : CommandBufferAccessContext(&sync_validator) {
John Zulauf3d84f1b2020-03-09 13:33:25 -06001001 cb_state_ = cb_state;
1002 queue_flags_ = queue_flags;
1003 }
John Zulauf4fa68462021-04-26 21:04:22 -06001004
1005 struct AsProxyContext {};
1006 CommandBufferAccessContext(const CommandBufferAccessContext &real_context, AsProxyContext dummy);
1007
John Zulauf64ffe552021-02-06 10:25:07 -07001008 ~CommandBufferAccessContext() override = default;
1009 CommandExecutionContext &GetExecutionContext() { return *this; }
1010 const CommandExecutionContext &GetExecutionContext() const { return *this; }
John Zulauf5c5e88d2019-12-26 11:22:02 -07001011
1012 void Reset() {
John Zulauf14940722021-04-12 15:19:02 -06001013 access_log_.clear();
John Zulauf3c2a0b32021-07-14 11:14:52 -06001014 cbs_referenced_.clear();
John Zulauf8eda1562021-04-13 17:06:41 -06001015 sync_ops_.clear();
John Zulauf355e49b2020-04-24 15:11:15 -06001016 command_number_ = 0;
John Zulauffaea0ee2021-01-14 14:01:32 -07001017 subcommand_number_ = 0;
John Zulauf355e49b2020-04-24 15:11:15 -06001018 reset_count_++;
1019 cb_access_context_.Reset();
John Zulauf3d84f1b2020-03-09 13:33:25 -06001020 render_pass_contexts_.clear();
John Zulauf355e49b2020-04-24 15:11:15 -06001021 current_context_ = &cb_access_context_;
John Zulauf3d84f1b2020-03-09 13:33:25 -06001022 current_renderpass_context_ = nullptr;
John Zulauf669dfd52021-01-27 17:15:28 -07001023 events_context_.Clear();
John Zulauf5c5e88d2019-12-26 11:22:02 -07001024 }
John Zulaufe7f6a5e2021-01-16 14:31:18 -07001025 void MarkDestroyed() { destroyed_ = true; }
1026 bool IsDestroyed() const { return destroyed_; }
John Zulauf5c5e88d2019-12-26 11:22:02 -07001027
John Zulauf4fa68462021-04-26 21:04:22 -06001028 std::string FormatUsage(ResourceUsageTag tag) const override;
1029 std::string FormatUsage(const ResourceFirstAccess &access) const override;
John Zulauf64ffe552021-02-06 10:25:07 -07001030 std::string FormatUsage(const HazardResult &hazard) const override;
John Zulauf540266b2020-04-06 18:54:53 -06001031 AccessContext *GetCurrentAccessContext() { return current_context_; }
John Zulauf669dfd52021-01-27 17:15:28 -07001032 SyncEventsContext *GetCurrentEventsContext() { return &events_context_; }
John Zulauf64ffe552021-02-06 10:25:07 -07001033 RenderPassAccessContext *GetCurrentRenderPassContext() { return current_renderpass_context_; }
John Zulauf540266b2020-04-06 18:54:53 -06001034 const AccessContext *GetCurrentAccessContext() const { return current_context_; }
John Zulauf64ffe552021-02-06 10:25:07 -07001035 const SyncEventsContext *GetCurrentEventsContext() const { return &events_context_; }
1036 const RenderPassAccessContext *GetCurrentRenderPassContext() const { return current_renderpass_context_; }
1037 void RecordBeginRenderPass(const RENDER_PASS_STATE &rp_state, const VkRect2D &render_area,
John Zulauf14940722021-04-12 15:19:02 -06001038 const std::vector<const IMAGE_VIEW_STATE *> &attachment_views, ResourceUsageTag tag);
Jeremy Gebben9893daf2021-01-04 10:40:50 -07001039 void ApplyGlobalBarriersToEvents(const SyncExecScope &src, const SyncExecScope &dst);
John Zulaufd5115702021-01-18 12:34:33 -07001040
locke-lunarg61870c22020-06-09 14:51:50 -06001041 bool ValidateDispatchDrawDescriptorSet(VkPipelineBindPoint pipelineBindPoint, const char *func_name) const;
John Zulauf14940722021-04-12 15:19:02 -06001042 void RecordDispatchDrawDescriptorSet(VkPipelineBindPoint pipelineBindPoint, ResourceUsageTag tag);
locke-lunarg61870c22020-06-09 14:51:50 -06001043 bool ValidateDrawVertex(uint32_t vertexCount, uint32_t firstVertex, const char *func_name) const;
John Zulauf14940722021-04-12 15:19:02 -06001044 void RecordDrawVertex(uint32_t vertexCount, uint32_t firstVertex, ResourceUsageTag tag);
locke-lunarg61870c22020-06-09 14:51:50 -06001045 bool ValidateDrawVertexIndex(uint32_t indexCount, uint32_t firstIndex, const char *func_name) const;
John Zulauf14940722021-04-12 15:19:02 -06001046 void RecordDrawVertexIndex(uint32_t indexCount, uint32_t firstIndex, ResourceUsageTag tag);
locke-lunarg61870c22020-06-09 14:51:50 -06001047 bool ValidateDrawSubpassAttachment(const char *func_name) const;
John Zulauf14940722021-04-12 15:19:02 -06001048 void RecordDrawSubpassAttachment(ResourceUsageTag tag);
John Zulauf8eda1562021-04-13 17:06:41 -06001049 void RecordNextSubpass(ResourceUsageTag prev_tag, ResourceUsageTag next_tag);
1050 void RecordEndRenderPass(ResourceUsageTag tag);
John Zulauf4a6105a2020-11-17 15:11:05 -07001051 void RecordDestroyEvent(VkEvent event);
John Zulauf49beb112020-11-04 16:06:31 -07001052
John Zulauf4fa68462021-04-26 21:04:22 -06001053 bool ValidateFirstUse(CommandBufferAccessContext *proxy_context, const char *func_name, uint32_t index) const;
1054 void RecordExecutedCommandBuffer(const CommandBufferAccessContext &recorded_context, CMD_TYPE cmd);
1055
1056 void ResolveRecordedContext(const AccessContext &recorded_context, ResourceUsageTag offset);
1057 ResourceUsageRange ImportRecordedAccessLog(const CommandBufferAccessContext &recorded_context);
John Zulaufae842002021-04-15 18:20:55 -06001058
John Zulauf3d84f1b2020-03-09 13:33:25 -06001059 const CMD_BUFFER_STATE *GetCommandBufferState() const { return cb_state_.get(); }
1060 VkQueueFlags GetQueueFlags() const { return queue_flags_; }
John Zulauffaea0ee2021-01-14 14:01:32 -07001061
1062 inline ResourceUsageTag NextSubcommandTag(CMD_TYPE command) {
John Zulauf14940722021-04-12 15:19:02 -06001063 ResourceUsageTag next = access_log_.size();
John Zulauf3c2a0b32021-07-14 11:14:52 -06001064 access_log_.emplace_back(command, command_number_, ++subcommand_number_, cb_state_.get(), reset_count_);
John Zulauffaea0ee2021-01-14 14:01:32 -07001065 return next;
1066 }
John Zulauf4fa68462021-04-26 21:04:22 -06001067 inline ResourceUsageTag GetTagLimit() const { return access_log_.size(); }
John Zulauffaea0ee2021-01-14 14:01:32 -07001068
John Zulauf355e49b2020-04-24 15:11:15 -06001069 inline ResourceUsageTag NextCommandTag(CMD_TYPE command) {
John Zulauf355e49b2020-04-24 15:11:15 -06001070 command_number_++;
John Zulauffaea0ee2021-01-14 14:01:32 -07001071 subcommand_number_ = 0;
John Zulauf14940722021-04-12 15:19:02 -06001072 ResourceUsageTag next = access_log_.size();
Jeremy Gebben6ea9d9e2020-12-11 09:41:01 -07001073 // The lowest bit is a sub-command number used to separate operations at the end of the previous renderpass
1074 // from the start of the new one in VkCmdNextRenderpass().
John Zulauf3c2a0b32021-07-14 11:14:52 -06001075 access_log_.emplace_back(command, command_number_, subcommand_number_, cb_state_.get(), reset_count_);
John Zulauf355e49b2020-04-24 15:11:15 -06001076 return next;
1077 }
John Zulauf3d84f1b2020-03-09 13:33:25 -06001078
John Zulauffaea0ee2021-01-14 14:01:32 -07001079 const CMD_BUFFER_STATE &GetCBState() const {
1080 assert(cb_state_);
1081 return *(cb_state_.get());
1082 }
1083 CMD_BUFFER_STATE &GetCBState() {
1084 assert(cb_state_);
1085 return *(cb_state_.get());
1086 }
John Zulauffaea0ee2021-01-14 14:01:32 -07001087
John Zulauf1bf30522021-09-03 15:39:06 -06001088 template <class T, class... Args>
1089 void RecordSyncOp(Args &&...args) {
1090 // T must be as derived from SyncOpBase or the compiler will flag the next line as an error.
1091 SyncOpPointer sync_op(std::make_shared<T>(std::forward<Args>(args)...));
1092 auto tag = sync_op->Record(this);
1093 AddSyncOp(tag, std::move(sync_op));
1094 }
John Zulauf8eda1562021-04-13 17:06:41 -06001095
John Zulauf3d84f1b2020-03-09 13:33:25 -06001096 private:
John Zulauf1bf30522021-09-03 15:39:06 -06001097 void AddSyncOp(ResourceUsageTag tag, SyncOpPointer &&sync_op) { sync_ops_.emplace_back(tag, std::move(sync_op)); }
John Zulauf4fa68462021-04-26 21:04:22 -06001098 std::shared_ptr<CMD_BUFFER_STATE> cb_state_;
1099 VkQueueFlags queue_flags_;
1100 bool destroyed_;
1101
John Zulauf14940722021-04-12 15:19:02 -06001102 std::vector<ResourceUsageRecord> access_log_;
John Zulauf3c2a0b32021-07-14 11:14:52 -06001103 layer_data::unordered_set<std::shared_ptr<const CMD_BUFFER_STATE>> cbs_referenced_;
John Zulauf355e49b2020-04-24 15:11:15 -06001104 uint32_t command_number_;
John Zulauffaea0ee2021-01-14 14:01:32 -07001105 uint32_t subcommand_number_;
John Zulauf355e49b2020-04-24 15:11:15 -06001106 uint32_t reset_count_;
John Zulauf4fa68462021-04-26 21:04:22 -06001107
John Zulauf355e49b2020-04-24 15:11:15 -06001108 AccessContext cb_access_context_;
John Zulauf540266b2020-04-06 18:54:53 -06001109 AccessContext *current_context_;
John Zulauf669dfd52021-01-27 17:15:28 -07001110 SyncEventsContext events_context_;
John Zulauf4fa68462021-04-26 21:04:22 -06001111
1112 // Don't need the following for an active proxy cb context
1113 std::vector<RenderPassAccessContext> render_pass_contexts_;
1114 RenderPassAccessContext *current_renderpass_context_;
1115 std::vector<SyncOpEntry> sync_ops_;
John Zulauf9cb530d2019-09-30 14:14:10 -06001116};
1117
1118class SyncValidator : public ValidationStateTracker, public SyncStageAccess {
1119 public:
1120 SyncValidator() { container_type = LayerObjectTypeSyncValidation; }
1121 using StateTracker = ValidationStateTracker;
1122
Jeremy Gebbencbf22862021-03-03 12:01:22 -07001123 layer_data::unordered_map<VkCommandBuffer, CommandBufferAccessContextShared> cb_access_state;
John Zulaufe7f6a5e2021-01-16 14:31:18 -07001124
1125 CommandBufferAccessContextShared GetAccessContextImpl(VkCommandBuffer command_buffer, bool do_insert) {
John Zulauf9cb530d2019-09-30 14:14:10 -06001126 auto found_it = cb_access_state.find(command_buffer);
1127 if (found_it == cb_access_state.end()) {
John Zulaufe7f6a5e2021-01-16 14:31:18 -07001128 if (!do_insert) return CommandBufferAccessContextShared();
John Zulauf9cb530d2019-09-30 14:14:10 -06001129 // If we don't have one, make it.
John Zulauf3d84f1b2020-03-09 13:33:25 -06001130 auto cb_state = GetShared<CMD_BUFFER_STATE>(command_buffer);
1131 assert(cb_state.get());
Jeremy Gebben159b3cc2021-06-03 09:09:03 -06001132 auto queue_flags = cb_state->GetQueueFlags();
John Zulaufe7f6a5e2021-01-16 14:31:18 -07001133 std::shared_ptr<CommandBufferAccessContext> context(new CommandBufferAccessContext(*this, cb_state, queue_flags));
Jeremy Gebbencbf22862021-03-03 12:01:22 -07001134 auto insert_pair = cb_access_state.emplace(command_buffer, std::move(context));
John Zulauf9cb530d2019-09-30 14:14:10 -06001135 found_it = insert_pair.first;
1136 }
John Zulaufe7f6a5e2021-01-16 14:31:18 -07001137 return found_it->second;
John Zulauf9cb530d2019-09-30 14:14:10 -06001138 }
John Zulaufe7f6a5e2021-01-16 14:31:18 -07001139
John Zulauf3d84f1b2020-03-09 13:33:25 -06001140 CommandBufferAccessContext *GetAccessContext(VkCommandBuffer command_buffer) {
John Zulaufe7f6a5e2021-01-16 14:31:18 -07001141 return GetAccessContextImpl(command_buffer, true).get(); // true -> do_insert on not found
John Zulauf9cb530d2019-09-30 14:14:10 -06001142 }
John Zulauf3d84f1b2020-03-09 13:33:25 -06001143 CommandBufferAccessContext *GetAccessContextNoInsert(VkCommandBuffer command_buffer) {
John Zulaufe7f6a5e2021-01-16 14:31:18 -07001144 return GetAccessContextImpl(command_buffer, false).get(); // false -> don't do_insert on not found
1145 }
1146
1147 CommandBufferAccessContextShared GetAccessContextShared(VkCommandBuffer command_buffer) {
1148 return GetAccessContextImpl(command_buffer, true); // true -> do_insert on not found
1149 }
1150 CommandBufferAccessContextShared GetAccessContextSharedNoInsert(VkCommandBuffer command_buffer) {
John Zulauf3d84f1b2020-03-09 13:33:25 -06001151 return GetAccessContextImpl(command_buffer, false); // false -> don't do_insert on not found
John Zulauf9cb530d2019-09-30 14:14:10 -06001152 }
John Zulauf3d84f1b2020-03-09 13:33:25 -06001153
1154 const CommandBufferAccessContext *GetAccessContext(VkCommandBuffer command_buffer) const {
John Zulauf9cb530d2019-09-30 14:14:10 -06001155 const auto found_it = cb_access_state.find(command_buffer);
1156 if (found_it == cb_access_state.end()) {
1157 return nullptr;
1158 }
1159 return found_it->second.get();
1160 }
1161
John Zulaufd1f85d42020-04-15 12:23:15 -06001162 void ResetCommandBufferCallback(VkCommandBuffer command_buffer);
1163 void FreeCommandBufferCallback(VkCommandBuffer command_buffer);
John Zulauf3d84f1b2020-03-09 13:33:25 -06001164 void RecordCmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *pRenderPassBegin,
sfricke-samsung85584a72021-09-30 21:43:38 -07001165 const VkSubpassBeginInfo *pSubpassBeginInfo, CMD_TYPE cmd);
John Zulauf64ffe552021-02-06 10:25:07 -07001166 void RecordCmdNextSubpass(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo *pSubpassBeginInfo,
sfricke-samsung85584a72021-09-30 21:43:38 -07001167 const VkSubpassEndInfo *pSubpassEndInfo, CMD_TYPE command);
1168 void RecordCmdEndRenderPass(VkCommandBuffer commandBuffer, const VkSubpassEndInfo *pSubpassEndInfo, CMD_TYPE cmd);
John Zulauf33fc1d52020-07-17 11:01:10 -06001169 bool SupressedBoundDescriptorWAW(const HazardResult &hazard) const;
John Zulauf9cb530d2019-09-30 14:14:10 -06001170
1171 void PostCallRecordCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001172 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, VkResult result) override;
John Zulauf9cb530d2019-09-30 14:14:10 -06001173
John Zulauf355e49b2020-04-24 15:11:15 -06001174 bool ValidateBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *pRenderPassBegin,
sfricke-samsung85584a72021-09-30 21:43:38 -07001175 const VkSubpassBeginInfo *pSubpassBeginInfo, CMD_TYPE cmd) const;
John Zulauf355e49b2020-04-24 15:11:15 -06001176
1177 bool PreCallValidateCmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *pRenderPassBegin,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001178 VkSubpassContents contents) const override;
John Zulauf355e49b2020-04-24 15:11:15 -06001179
1180 bool PreCallValidateCmdBeginRenderPass2KHR(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *pRenderPassBegin,
Mike Schuchardt2df08912020-12-15 16:28:09 -08001181 const VkSubpassBeginInfo *pSubpassBeginInfo) const override;
John Zulauf355e49b2020-04-24 15:11:15 -06001182
1183 bool PreCallValidateCmdBeginRenderPass2(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *pRenderPassBegin,
Mike Schuchardt2df08912020-12-15 16:28:09 -08001184 const VkSubpassBeginInfo *pSubpassBeginInfo) const override;
John Zulauf355e49b2020-04-24 15:11:15 -06001185
John Zulauf9cb530d2019-09-30 14:14:10 -06001186 bool PreCallValidateCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001187 const VkBufferCopy *pRegions) const override;
John Zulauf9cb530d2019-09-30 14:14:10 -06001188
1189 void PreCallRecordCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001190 const VkBufferCopy *pRegions) override;
John Zulauf9cb530d2019-09-30 14:14:10 -06001191
John Zulauf4a6105a2020-11-17 15:11:05 -07001192 void PreCallRecordDestroyEvent(VkDevice device, VkEvent event, const VkAllocationCallbacks *pAllocator) override;
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001193 bool PreCallValidateCmdCopyBuffer2KHR(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2KHR *pCopyBufferInfos) const override;
Jeff Leger178b1e52020-10-05 12:22:23 -04001194
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001195 void PreCallRecordCmdCopyBuffer2KHR(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2KHR *pCopyBufferInfos) override;
Jeff Leger178b1e52020-10-05 12:22:23 -04001196
John Zulauf5c5e88d2019-12-26 11:22:02 -07001197 bool PreCallValidateCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
1198 VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001199 const VkImageCopy *pRegions) const override;
John Zulauf5c5e88d2019-12-26 11:22:02 -07001200
1201 void PreCallRecordCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001202 VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy *pRegions) override;
John Zulauf5c5e88d2019-12-26 11:22:02 -07001203
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001204 bool PreCallValidateCmdCopyImage2KHR(VkCommandBuffer commandBuffer, const VkCopyImageInfo2KHR *pCopyImageInfo) const override;
Jeff Leger178b1e52020-10-05 12:22:23 -04001205
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001206 void PreCallRecordCmdCopyImage2KHR(VkCommandBuffer commandBuffer, const VkCopyImageInfo2KHR *pCopyImageInfo) override;
Jeff Leger178b1e52020-10-05 12:22:23 -04001207
John Zulauf9cb530d2019-09-30 14:14:10 -06001208 bool PreCallValidateCmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask,
1209 VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags,
1210 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
1211 uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers,
1212 uint32_t imageMemoryBarrierCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001213 const VkImageMemoryBarrier *pImageMemoryBarriers) const override;
John Zulauf9cb530d2019-09-30 14:14:10 -06001214
1215 void PreCallRecordCmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask,
1216 VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags,
1217 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
1218 uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001219 uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) override;
John Zulauf3d84f1b2020-03-09 13:33:25 -06001220
Jeremy Gebbendf3fcc32021-02-15 08:53:17 -07001221 bool PreCallValidateCmdPipelineBarrier2KHR(VkCommandBuffer commandBuffer,
1222 const VkDependencyInfoKHR *pDependencyInfo) const override;
1223 void PreCallRecordCmdPipelineBarrier2KHR(VkCommandBuffer commandBuffer, const VkDependencyInfoKHR *pDependencyInfo) override;
1224
John Zulauf3d84f1b2020-03-09 13:33:25 -06001225 void PostCallRecordBeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001226 VkResult result) override;
John Zulauf3d84f1b2020-03-09 13:33:25 -06001227
1228 void PostCallRecordCmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *pRenderPassBegin,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001229 VkSubpassContents contents) override;
John Zulauf3d84f1b2020-03-09 13:33:25 -06001230 void PostCallRecordCmdBeginRenderPass2(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *pRenderPassBegin,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001231 const VkSubpassBeginInfo *pSubpassBeginInfo) override;
John Zulauf3d84f1b2020-03-09 13:33:25 -06001232 void PostCallRecordCmdBeginRenderPass2KHR(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *pRenderPassBegin,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001233 const VkSubpassBeginInfo *pSubpassBeginInfo) override;
John Zulauf3d84f1b2020-03-09 13:33:25 -06001234
Mike Schuchardt2df08912020-12-15 16:28:09 -08001235 bool ValidateCmdNextSubpass(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo *pSubpassBeginInfo,
sfricke-samsung85584a72021-09-30 21:43:38 -07001236 const VkSubpassEndInfo *pSubpassEndInfo, CMD_TYPE cmd) const;
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001237 bool PreCallValidateCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) const override;
Mike Schuchardt2df08912020-12-15 16:28:09 -08001238 bool PreCallValidateCmdNextSubpass2(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo *pSubpassBeginInfo,
1239 const VkSubpassEndInfo *pSubpassEndInfo) const override;
1240 bool PreCallValidateCmdNextSubpass2KHR(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo *pSubpassBeginInfo,
1241 const VkSubpassEndInfo *pSubpassEndInfo) const override;
John Zulauf355e49b2020-04-24 15:11:15 -06001242
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001243 void PostCallRecordCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) override;
John Zulauf3d84f1b2020-03-09 13:33:25 -06001244 void PostCallRecordCmdNextSubpass2(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo *pSubpassBeginInfo,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001245 const VkSubpassEndInfo *pSubpassEndInfo) override;
John Zulauf3d84f1b2020-03-09 13:33:25 -06001246 void PostCallRecordCmdNextSubpass2KHR(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo *pSubpassBeginInfo,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001247 const VkSubpassEndInfo *pSubpassEndInfo) override;
John Zulauf3d84f1b2020-03-09 13:33:25 -06001248
sfricke-samsung85584a72021-09-30 21:43:38 -07001249 bool ValidateCmdEndRenderPass(VkCommandBuffer commandBuffer, const VkSubpassEndInfo *pSubpassEndInfo, CMD_TYPE cmd) const;
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001250 bool PreCallValidateCmdEndRenderPass(VkCommandBuffer commandBuffer) const override;
Mike Schuchardt2df08912020-12-15 16:28:09 -08001251 bool PreCallValidateCmdEndRenderPass2KHR(VkCommandBuffer commandBuffer, const VkSubpassEndInfo *pSubpassEndInfo) const override;
1252 bool PreCallValidateCmdEndRenderPass2(VkCommandBuffer commandBuffer, const VkSubpassEndInfo *pSubpassEndInfo) const override;
John Zulauf355e49b2020-04-24 15:11:15 -06001253
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001254 void PostCallRecordCmdEndRenderPass(VkCommandBuffer commandBuffer) override;
1255 void PostCallRecordCmdEndRenderPass2(VkCommandBuffer commandBuffer, const VkSubpassEndInfo *pSubpassEndInfo) override;
1256 void PostCallRecordCmdEndRenderPass2KHR(VkCommandBuffer commandBuffer, const VkSubpassEndInfo *pSubpassEndInfo) override;
Jeff Leger178b1e52020-10-05 12:22:23 -04001257
1258 template <typename BufferImageCopyRegionType>
1259 bool ValidateCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage,
1260 VkImageLayout dstImageLayout, uint32_t regionCount, const BufferImageCopyRegionType *pRegions,
1261 CopyCommandVersion version) const;
locke-lunarga19c71d2020-03-02 18:17:04 -07001262 bool PreCallValidateCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage,
1263 VkImageLayout dstImageLayout, uint32_t regionCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001264 const VkBufferImageCopy *pRegions) const override;
Jeff Leger178b1e52020-10-05 12:22:23 -04001265 bool PreCallValidateCmdCopyBufferToImage2KHR(VkCommandBuffer commandBuffer,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001266 const VkCopyBufferToImageInfo2KHR *pCopyBufferToImageInfo) const override;
locke-lunarga19c71d2020-03-02 18:17:04 -07001267
Jeff Leger178b1e52020-10-05 12:22:23 -04001268 template <typename BufferImageCopyRegionType>
1269 void RecordCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage,
1270 VkImageLayout dstImageLayout, uint32_t regionCount, const BufferImageCopyRegionType *pRegions,
1271 CopyCommandVersion version);
locke-lunarga19c71d2020-03-02 18:17:04 -07001272 void PreCallRecordCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001273 VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy *pRegions) override;
Jeff Leger178b1e52020-10-05 12:22:23 -04001274 void PreCallRecordCmdCopyBufferToImage2KHR(VkCommandBuffer commandBuffer,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001275 const VkCopyBufferToImageInfo2KHR *pCopyBufferToImageInfo) override;
locke-lunarga19c71d2020-03-02 18:17:04 -07001276
Jeff Leger178b1e52020-10-05 12:22:23 -04001277 template <typename BufferImageCopyRegionType>
1278 bool ValidateCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
1279 VkBuffer dstBuffer, uint32_t regionCount, const BufferImageCopyRegionType *pRegions,
1280 CopyCommandVersion version) const;
locke-lunarga19c71d2020-03-02 18:17:04 -07001281 bool PreCallValidateCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001282 VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy *pRegions) const override;
Jeff Leger178b1e52020-10-05 12:22:23 -04001283 bool PreCallValidateCmdCopyImageToBuffer2KHR(VkCommandBuffer commandBuffer,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001284 const VkCopyImageToBufferInfo2KHR *pCopyImageToBufferInfo) const override;
locke-lunarga19c71d2020-03-02 18:17:04 -07001285
Jeff Leger178b1e52020-10-05 12:22:23 -04001286 template <typename BufferImageCopyRegionType>
1287 void RecordCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
1288 VkBuffer dstBuffer, uint32_t regionCount, const BufferImageCopyRegionType *pRegions,
1289 CopyCommandVersion version);
locke-lunarga19c71d2020-03-02 18:17:04 -07001290 void PreCallRecordCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001291 VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy *pRegions) override;
Jeff Leger178b1e52020-10-05 12:22:23 -04001292 void PreCallRecordCmdCopyImageToBuffer2KHR(VkCommandBuffer commandBuffer,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001293 const VkCopyImageToBufferInfo2KHR *pCopyImageToBufferInfo) override;
Jeff Leger178b1e52020-10-05 12:22:23 -04001294
1295 template <typename RegionType>
1296 bool ValidateCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage,
1297 VkImageLayout dstImageLayout, uint32_t regionCount, const RegionType *pRegions, VkFilter filter,
1298 const char *apiName) const;
locke-lunarga19c71d2020-03-02 18:17:04 -07001299
1300 bool PreCallValidateCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
1301 VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001302 const VkImageBlit *pRegions, VkFilter filter) const override;
1303 bool PreCallValidateCmdBlitImage2KHR(VkCommandBuffer commandBuffer, const VkBlitImageInfo2KHR *pBlitImageInfo) const override;
locke-lunarga19c71d2020-03-02 18:17:04 -07001304
Jeff Leger178b1e52020-10-05 12:22:23 -04001305 template <typename RegionType>
1306 void RecordCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage,
1307 VkImageLayout dstImageLayout, uint32_t regionCount, const RegionType *pRegions, VkFilter filter,
1308 ResourceUsageTag tag);
locke-lunarga19c71d2020-03-02 18:17:04 -07001309 void PreCallRecordCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage,
1310 VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit *pRegions,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001311 VkFilter filter) override;
1312 void PreCallRecordCmdBlitImage2KHR(VkCommandBuffer commandBuffer, const VkBlitImageInfo2KHR *pBlitImageInfo) override;
locke-lunarg36ba2592020-04-03 09:42:04 -06001313
John Zulauffaea0ee2021-01-14 14:01:32 -07001314 bool ValidateIndirectBuffer(const CommandBufferAccessContext &cb_context, const AccessContext &context,
1315 VkCommandBuffer commandBuffer, const VkDeviceSize struct_size, const VkBuffer buffer,
1316 const VkDeviceSize offset, const uint32_t drawCount, const uint32_t stride,
locke-lunarg61870c22020-06-09 14:51:50 -06001317 const char *function) const;
John Zulauf14940722021-04-12 15:19:02 -06001318 void RecordIndirectBuffer(AccessContext &context, ResourceUsageTag tag, const VkDeviceSize struct_size, const VkBuffer buffer,
1319 const VkDeviceSize offset, const uint32_t drawCount, uint32_t stride);
locke-lunarg36ba2592020-04-03 09:42:04 -06001320
John Zulauffaea0ee2021-01-14 14:01:32 -07001321 bool ValidateCountBuffer(const CommandBufferAccessContext &cb_context, const AccessContext &context,
1322 VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, const char *function) const;
John Zulauf14940722021-04-12 15:19:02 -06001323 void RecordCountBuffer(AccessContext &context, ResourceUsageTag tag, VkBuffer buffer, VkDeviceSize offset);
locke-lunarg93d68af2020-05-12 17:18:03 -06001324
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001325 bool PreCallValidateCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) const override;
1326 void PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) override;
locke-lunarge1a67022020-04-29 00:15:36 -06001327
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001328 bool PreCallValidateCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) const override;
1329 void PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) override;
locke-lunarge1a67022020-04-29 00:15:36 -06001330
1331 bool PreCallValidateCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001332 uint32_t firstInstance) const override;
locke-lunarge1a67022020-04-29 00:15:36 -06001333 void PreCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001334 uint32_t firstInstance) override;
locke-lunarge1a67022020-04-29 00:15:36 -06001335
1336 bool PreCallValidateCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001337 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) const override;
locke-lunarge1a67022020-04-29 00:15:36 -06001338 void PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001339 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) override;
locke-lunarge1a67022020-04-29 00:15:36 -06001340
1341 bool PreCallValidateCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001342 uint32_t stride) const override;
locke-lunarge1a67022020-04-29 00:15:36 -06001343 void PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001344 uint32_t stride) override;
locke-lunarge1a67022020-04-29 00:15:36 -06001345
1346 bool PreCallValidateCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001347 uint32_t drawCount, uint32_t stride) const override;
locke-lunarge1a67022020-04-29 00:15:36 -06001348 void PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001349 uint32_t drawCount, uint32_t stride) override;
locke-lunarge1a67022020-04-29 00:15:36 -06001350
locke-lunargff255f92020-05-13 18:53:52 -06001351 bool ValidateCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer,
1352 VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride,
1353 const char *function) const;
locke-lunarge1a67022020-04-29 00:15:36 -06001354 bool PreCallValidateCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1355 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001356 uint32_t stride) const override;
sfricke-samsung85584a72021-09-30 21:43:38 -07001357 void RecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer,
1358 VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride, CMD_TYPE cmd_type);
locke-lunarge1a67022020-04-29 00:15:36 -06001359 void PreCallRecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1360 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001361 uint32_t stride) override;
locke-lunarge1a67022020-04-29 00:15:36 -06001362 bool PreCallValidateCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1363 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001364 uint32_t stride) const override;
locke-lunarge1a67022020-04-29 00:15:36 -06001365 void PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1366 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001367 uint32_t stride) override;
locke-lunarge1a67022020-04-29 00:15:36 -06001368 bool PreCallValidateCmdDrawIndirectCountAMD(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1369 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001370 uint32_t stride) const override;
locke-lunarge1a67022020-04-29 00:15:36 -06001371 void PreCallRecordCmdDrawIndirectCountAMD(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1372 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001373 uint32_t stride) override;
locke-lunarge1a67022020-04-29 00:15:36 -06001374
locke-lunargff255f92020-05-13 18:53:52 -06001375 bool ValidateCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1376 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
1377 uint32_t stride, const char *function) const;
locke-lunarge1a67022020-04-29 00:15:36 -06001378 bool PreCallValidateCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1379 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001380 uint32_t stride) const override;
sfricke-samsung85584a72021-09-30 21:43:38 -07001381 void RecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1382 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
1383 uint32_t stride, CMD_TYPE cmd_type);
locke-lunarge1a67022020-04-29 00:15:36 -06001384 void PreCallRecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1385 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001386 uint32_t stride) override;
locke-lunarge1a67022020-04-29 00:15:36 -06001387 bool PreCallValidateCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1388 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001389 uint32_t stride) const override;
locke-lunarge1a67022020-04-29 00:15:36 -06001390 void PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1391 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001392 uint32_t stride) override;
locke-lunarge1a67022020-04-29 00:15:36 -06001393 bool PreCallValidateCmdDrawIndexedIndirectCountAMD(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1394 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001395 uint32_t stride) const override;
locke-lunarge1a67022020-04-29 00:15:36 -06001396 void PreCallRecordCmdDrawIndexedIndirectCountAMD(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1397 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001398 uint32_t stride) override;
locke-lunarge1a67022020-04-29 00:15:36 -06001399
1400 bool PreCallValidateCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout,
1401 const VkClearColorValue *pColor, uint32_t rangeCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001402 const VkImageSubresourceRange *pRanges) const override;
locke-lunarge1a67022020-04-29 00:15:36 -06001403 void PreCallRecordCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout,
1404 const VkClearColorValue *pColor, uint32_t rangeCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001405 const VkImageSubresourceRange *pRanges) override;
locke-lunarge1a67022020-04-29 00:15:36 -06001406
1407 bool PreCallValidateCmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout,
1408 const VkClearDepthStencilValue *pDepthStencil, uint32_t rangeCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001409 const VkImageSubresourceRange *pRanges) const override;
locke-lunarge1a67022020-04-29 00:15:36 -06001410 void PreCallRecordCmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout,
1411 const VkClearDepthStencilValue *pDepthStencil, uint32_t rangeCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001412 const VkImageSubresourceRange *pRanges) override;
locke-lunarge1a67022020-04-29 00:15:36 -06001413
1414 bool PreCallValidateCmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery,
1415 uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001416 VkDeviceSize stride, VkQueryResultFlags flags) const override;
locke-lunarge1a67022020-04-29 00:15:36 -06001417 void PreCallRecordCmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery,
1418 uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001419 VkQueryResultFlags flags) override;
locke-lunarge1a67022020-04-29 00:15:36 -06001420
1421 bool PreCallValidateCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001422 uint32_t data) const override;
locke-lunarge1a67022020-04-29 00:15:36 -06001423 void PreCallRecordCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001424 uint32_t data) override;
locke-lunarge1a67022020-04-29 00:15:36 -06001425
1426 bool PreCallValidateCmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
1427 VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001428 const VkImageResolve *pRegions) const override;
Jeff Leger178b1e52020-10-05 12:22:23 -04001429
locke-lunarge1a67022020-04-29 00:15:36 -06001430 void PreCallRecordCmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
1431 VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001432 const VkImageResolve *pRegions) override;
locke-lunarge1a67022020-04-29 00:15:36 -06001433
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001434 bool PreCallValidateCmdResolveImage2KHR(VkCommandBuffer commandBuffer, const VkResolveImageInfo2KHR *pResolveImageInfo) const override;
1435 void PreCallRecordCmdResolveImage2KHR(VkCommandBuffer commandBuffer, const VkResolveImageInfo2KHR *pResolveImageInfo) override;
Jeff Leger178b1e52020-10-05 12:22:23 -04001436
locke-lunarge1a67022020-04-29 00:15:36 -06001437 bool PreCallValidateCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001438 VkDeviceSize dataSize, const void *pData) const override;
locke-lunarge1a67022020-04-29 00:15:36 -06001439 void PreCallRecordCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001440 VkDeviceSize dataSize, const void *pData) override;
locke-lunargff255f92020-05-13 18:53:52 -06001441
1442 bool PreCallValidateCmdWriteBufferMarkerAMD(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001443 VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker) const override;
locke-lunargff255f92020-05-13 18:53:52 -06001444 void PreCallRecordCmdWriteBufferMarkerAMD(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage,
Jeremy Gebbenf8924692020-10-28 16:27:14 -06001445 VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker) override;
John Zulauf49beb112020-11-04 16:06:31 -07001446
1447 bool PreCallValidateCmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) const override;
1448 void PostCallRecordCmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) override;
1449
John Zulauf4edde622021-02-15 08:54:50 -07001450 bool PreCallValidateCmdSetEvent2KHR(VkCommandBuffer commandBuffer, VkEvent event,
1451 const VkDependencyInfoKHR *pDependencyInfo) const override;
1452 void PostCallRecordCmdSetEvent2KHR(VkCommandBuffer commandBuffer, VkEvent event,
1453 const VkDependencyInfoKHR *pDependencyInfo) override;
1454
John Zulauf49beb112020-11-04 16:06:31 -07001455 bool PreCallValidateCmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) const override;
1456 void PostCallRecordCmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) override;
1457
John Zulauf4edde622021-02-15 08:54:50 -07001458 bool PreCallValidateCmdResetEvent2KHR(VkCommandBuffer commandBuffer, VkEvent event,
1459 VkPipelineStageFlags2KHR stageMask) const override;
1460 void PostCallRecordCmdResetEvent2KHR(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2KHR stageMask) override;
1461
John Zulauf49beb112020-11-04 16:06:31 -07001462 bool PreCallValidateCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
1463 VkPipelineStageFlags sourceStageMask, VkPipelineStageFlags dstStageMask,
1464 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
1465 uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers,
1466 uint32_t imageMemoryBarrierCount,
1467 const VkImageMemoryBarrier *pImageMemoryBarriers) const override;
1468 void PostCallRecordCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
1469 VkPipelineStageFlags sourceStageMask, VkPipelineStageFlags dstStageMask,
1470 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
1471 uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers,
1472 uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) override;
John Zulauf4edde622021-02-15 08:54:50 -07001473 bool PreCallValidateCmdWaitEvents2KHR(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
1474 const VkDependencyInfoKHR *pDependencyInfos) const override;
1475 void PostCallRecordCmdWaitEvents2KHR(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
1476 const VkDependencyInfoKHR *pDependencyInfos) override;
Jeremy Gebbendf3fcc32021-02-15 08:53:17 -07001477 bool PreCallValidateCmdWriteBufferMarker2AMD(VkCommandBuffer commandBuffer, VkPipelineStageFlags2KHR stage, VkBuffer dstBuffer,
1478 VkDeviceSize dstOffset, uint32_t marker) const override;
1479 void PreCallRecordCmdWriteBufferMarker2AMD(VkCommandBuffer commandBuffer, VkPipelineStageFlags2KHR stage, VkBuffer dstBuffer,
1480 VkDeviceSize dstOffset, uint32_t marker) override;
John Zulaufae842002021-04-15 18:20:55 -06001481 bool PreCallValidateCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount,
1482 const VkCommandBuffer *pCommandBuffers) const override;
1483 void PreCallRecordCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount,
1484 const VkCommandBuffer *pCommandBuffers) override;
John Zulauf9cb530d2019-09-30 14:14:10 -06001485};