@@ -113,24 +113,10 @@ void CommandBuffer::WriteCommandEndCheckpoint(uint32_t command_id) {
113113 }
114114}
115115
116- bool CommandBuffer::WasSubmittedToQueue () const { return buffer_state_ == CommandBufferState::kPending ; }
117-
118- bool CommandBuffer::StartedExecution () const {
119- if (!checkpoint_) {
120- return false ;
121- }
122- return (checkpoint_->ReadTop () > begin_value_);
123- }
124-
125- bool CommandBuffer::CompletedExecution () const {
126- if (!checkpoint_) {
127- return false ;
128- }
129- return (checkpoint_->ReadBottom () >= end_value_);
130- }
116+ bool CommandBuffer::WasSubmittedToQueue () const { return buffer_state_ >= CommandBufferState::kSubmitted ; }
131117
132118void CommandBuffer::Reset () {
133- buffer_state_ = CommandBufferState::kInitialReset ;
119+ buffer_state_ = CommandBufferState::kReset ;
134120
135121 // Reset marker state.
136122 if (checkpoint_) {
@@ -150,7 +136,7 @@ void CommandBuffer::Reset() {
150136}
151137
152138void CommandBuffer::QueueSubmit (VkQueue queue, uint64_t queue_seq, VkFence fence) {
153- buffer_state_ = CommandBufferState::kPending ;
139+ buffer_state_ = CommandBufferState::kSubmitted ;
154140 submitted_queue_ = queue;
155141 submitted_queue_seq_ = queue_seq;
156142 submitted_fence_ = fence;
@@ -168,7 +154,7 @@ VkResult CommandBuffer::PreBeginCommandBuffer(VkCommandBuffer commandBuffer,
168154VkResult CommandBuffer::PostBeginCommandBuffer (VkCommandBuffer commandBuffer,
169155 const VkCommandBufferBeginInfo* pBeginInfo, VkResult result) {
170156 // Begin recording commands.
171- buffer_state_ = CommandBufferState::kRecording ;
157+ buffer_state_ = CommandBufferState::kBeginCalled ;
172158
173159 if (pBeginInfo->flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT) {
174160 cb_simultaneous_use_ = true ;
@@ -196,7 +182,7 @@ VkResult CommandBuffer::PreEndCommandBuffer(VkCommandBuffer commandBuffer) {
196182}
197183
198184VkResult CommandBuffer::PostEndCommandBuffer (VkCommandBuffer commandBuffer, VkResult result) {
199- buffer_state_ = CommandBufferState::kExecutable ;
185+ buffer_state_ = CommandBufferState::kEndCalled ;
200186
201187 return result;
202188}
@@ -237,110 +223,125 @@ uint32_t CommandBuffer::GetLastCompleteCommand() const {
237223 return marker - begin_value_;
238224}
239225
240- CommandBufferState CommandBuffer::GetCommandBufferState () const {
241- if (!checkpoint_ || (IsPrimaryCommandBuffer () && !WasSubmittedToQueue ())) {
242- return buffer_state_;
226+ void CommandBuffer::UpdateStateFromCheckpoints () {
227+ assert (WasSubmittedToQueue ());
228+ if (!HasCheckpoints ()) {
229+ return ;
230+ }
231+ // If the queue timeline semaphore has already signaled, don't
232+ // look at the checkpoints
233+ if (buffer_state_ == CommandBufferState::kCompleted ) {
234+ return ;
243235 }
236+ auto top = checkpoint_->ReadTop ();
237+ auto bottom = checkpoint_->ReadBottom ();
238+ auto prev_state = buffer_state_;
239+
244240 // If the command buffer is submitted and markers can be used, determine the
245241 // execution state of the command buffer.
246- if (!StartedExecution ()) {
247- return CommandBufferState::kSubmittedExecutionNotStarted ;
248- }
249- if (!CompletedExecution ()) {
250- return CommandBufferState::kSubmittedExecutionIncomplete ;
242+ if (top < begin_value_) {
243+ buffer_state_ = CommandBufferState::kNotStarted ;
244+ } else if (bottom < end_value_) {
245+ buffer_state_ = CommandBufferState::kIncomplete ;
246+ } else {
247+ buffer_state_ = CommandBufferState::kMaybeComplete ;
251248 }
252- return CommandBufferState::kSubmittedExecutionCompleted ;
249+
250+ device_.Log ().Verbose (" %s seq: %lld top: %d bottom: %d prev_state: %s state: %s" ,
251+ device_.GetObjectName ((uint64_t )vk_command_buffer_).c_str (), submitted_queue_seq_, top,
252+ bottom, PrintCommandBufferState (prev_state), PrintCommandBufferState (buffer_state_));
253253}
254254
255- CommandBufferState CommandBuffer::GetSecondaryCommandBufferState (
256- CommandState vkcmd_execute_commands_command_state) const {
257- assert (vkcmd_execute_commands_command_state != CommandState::kInvalidState );
258- if (vkcmd_execute_commands_command_state == CommandState::kCommandNotSubmitted ) {
259- return CommandBufferState::kNotSubmitted ;
260- }
261- if (vkcmd_execute_commands_command_state == CommandState::kCommandNotStarted ) {
262- return CommandBufferState::kSubmittedExecutionNotStarted ;
263- }
264- if (vkcmd_execute_commands_command_state == CommandState::kCommandCompleted ) {
265- return CommandBufferState::kSubmittedExecutionCompleted ;
255+ void CommandBuffer::UpdateSecondaryState (CommandState exec_cmds_state) {
256+ if (exec_cmds_state == CommandState::kNotSubmitted ||
257+ exec_cmds_state == CommandState::kInvalidState ) {
258+ return ;
266259 }
267- return GetCommandBufferState ();
260+ buffer_state_ = CommandBufferState::kSubmitted ;
261+ UpdateStateFromCheckpoints ();
262+ }
263+
264+ CommandBufferState CommandBuffer::GetCommandBufferState () const {
265+ return buffer_state_;
268266}
269267
270- std::string CommandBuffer::PrintCommandBufferState (CommandBufferState cb_state) const {
268+ const char * CommandBuffer::PrintCommandBufferState (CommandBufferState cb_state) const {
271269 switch (cb_state) {
272- case CommandBufferState::kInitial :
270+ case CommandBufferState::kCreated :
273271 return " CREATED" ;
274- case CommandBufferState::kRecording :
272+ case CommandBufferState::kBeginCalled :
275273 return " BEGIN_CALLED" ;
276- case CommandBufferState::kExecutable :
274+ case CommandBufferState::kEndCalled :
277275 return " END_CALLED" ;
278- case CommandBufferState::kPending :
276+ case CommandBufferState::kSubmitted :
279277 return " SUBMITTED" ;
280278 case CommandBufferState::kInvalid :
281279 return " INVALID" ;
282- case CommandBufferState::kInitialReset :
280+ case CommandBufferState::kReset :
283281 return " RESET" ;
284- case CommandBufferState::kSubmittedExecutionNotStarted :
282+ case CommandBufferState::kNotStarted :
285283 return " NOT_STARTED" ;
286- case CommandBufferState::kSubmittedExecutionIncomplete :
284+ case CommandBufferState::kIncomplete :
287285 return " INCOMPLETE" ;
288- case CommandBufferState::kSubmittedExecutionCompleted :
286+ case CommandBufferState::kMaybeComplete :
289287 return " MAYBE_COMPLETE" ;
290- case CommandBufferState::kQueueCompleted :
288+ case CommandBufferState::kCompleted :
291289 return " COMPLETED" ;
292- case CommandBufferState::kNotSubmitted :
293- return " NOT_SUBMITTED" ;
294- default :
295- assert (true );
296- return " UNKNOWN" ;
297290 }
291+ assert (false );
292+ return " UNKNOWN" ;
298293}
299294
300- CommandState CommandBuffer::GetCommandState (CommandBufferState cb_state, const Command& command) const {
301- if (IsPrimaryCommandBuffer () && !WasSubmittedToQueue ()) {
302- return CommandState::kCommandNotSubmitted ;
303- }
304- if (!checkpoint_) {
305- return CommandState::kCommandPending ;
306- }
307- if (!IsPrimaryCommandBuffer ()) {
308- if (cb_state == CommandBufferState::kNotSubmitted ) {
309- return CommandState::kCommandNotSubmitted ;
310- }
311- if (cb_state == CommandBufferState::kSubmittedExecutionNotStarted ) {
312- return CommandState::kCommandNotStarted ;
313- }
314- if (cb_state == CommandBufferState::kSubmittedExecutionCompleted ) {
315- return CommandState::kCommandCompleted ;
316- }
317- assert (cb_state == CommandBufferState::kSubmittedExecutionIncomplete );
318- }
319- if (command.id > GetLastStartedCommand ()) {
320- return CommandState::kCommandNotStarted ;
321- }
322- if (command.id <= GetLastCompleteCommand ()) {
323- return CommandState::kCommandCompleted ;
295+ static CommandState GetCommandState (CommandBufferState cb_state, const Command& command, uint32_t last_started,
296+ uint32_t last_completed) {
297+ switch (cb_state) {
298+ case CommandBufferState::kCreated :
299+ case CommandBufferState::kBeginCalled :
300+ case CommandBufferState::kEndCalled :
301+ case CommandBufferState::kReset :
302+ return CommandState::kNotSubmitted ;
303+
304+ case CommandBufferState::kSubmitted :
305+ return CommandState::kSubmitted ;
306+
307+ case CommandBufferState::kNotStarted :
308+ return CommandState::kNotStarted ;
309+
310+ case CommandBufferState::kIncomplete :
311+ case CommandBufferState::kMaybeComplete :
312+ if (command.id > last_started) {
313+ return CommandState::kNotStarted ;
314+ } else if (command.id <= last_completed) {
315+ return CommandState::kCompleted ;
316+ }
317+ return CommandState::kIncomplete ;
318+
319+ case CommandBufferState::kCompleted :
320+ return CommandState::kCompleted ;
321+
322+ case CommandBufferState::kInvalid :
323+ return CommandState::kInvalidState ;
324324 }
325- return CommandState::kCommandIncomplete ;
325+ return CommandState::kInvalidState ;
326326}
327327
328- std::string CommandBuffer::PrintCommandState (CommandState cm_state) const {
328+ const char * CommandBuffer::PrintCommandState (CommandState cm_state) const {
329329 switch (cm_state) {
330- case CommandState::kCommandNotSubmitted :
330+ case CommandState::kNotSubmitted :
331331 return " NOT_SUBMITTED" ;
332- case CommandState::kCommandPending :
332+ case CommandState::kSubmitted :
333333 return " SUBMITTED" ;
334- case CommandState::kCommandNotStarted :
334+ case CommandState::kNotStarted :
335335 return " NOT_STARTED" ;
336- case CommandState::kCommandIncomplete :
336+ case CommandState::kIncomplete :
337337 return " INCOMPLETE" ;
338- case CommandState::kCommandCompleted :
338+ case CommandState::kCompleted :
339339 return " COMPLETED" ;
340- default :
341- assert (true );
342- return " UNKNOWN" ;
340+ case CommandState::kInvalidState :
341+ return " INVALID" ;
343342 }
343+ assert (false );
344+ return " UNKNOWN" ;
344345}
345346
346347bool CommandBuffer::DumpCommand (const Command& command, YAML::Emitter& os) {
@@ -360,7 +361,8 @@ bool CommandBuffer::DumpCmdExecuteCommands(const Command& command, CommandState
360361 for (uint32_t i = 0 ; i < args->commandBufferCount ; i++) {
361362 auto secondary_command_buffer = crash_diagnostic_layer::GetCommandBuffer (args->pCommandBuffers [i]);
362363 if (secondary_command_buffer) {
363- secondary_command_buffer->DumpContents (os, settings, submitted_queue_seq_, command_state);
364+ secondary_command_buffer->UpdateSecondaryState (command_state);
365+ secondary_command_buffer->DumpContents (os, settings, submitted_queue_seq_);
364366 }
365367 }
366368 }
@@ -494,18 +496,13 @@ void CommandBuffer::DumpContents(YAML::Emitter& os, const Settings& settings, ui
494496 if (vk_command_buffer_ == VK_NULL_HANDLE) {
495497 return ;
496498 }
497- CommandBufferState cb_state;
498- if (IsPrimaryCommandBuffer ()) {
499- cb_state = GetCommandBufferState ();
500- } else {
501- cb_state = GetSecondaryCommandBufferState (vkcmd_execute_commands_command_state);
502- }
499+ CommandBufferState cb_state = GetCommandBufferState ();
503500 auto dump_cbs = settings.dump_command_buffers ;
504501 switch (cb_state) {
505- case CommandBufferState::kSubmittedExecutionIncomplete :
506- case CommandBufferState::kSubmittedExecutionCompleted :
502+ case CommandBufferState::kIncomplete :
503+ case CommandBufferState::kMaybeComplete :
507504 break ;
508- case CommandBufferState::kSubmittedExecutionNotStarted :
505+ case CommandBufferState::kNotStarted :
509506 if (dump_cbs == DumpCommands::kRunning ) {
510507 return ;
511508 }
@@ -523,7 +520,7 @@ void CommandBuffer::DumpContents(YAML::Emitter& os, const Settings& settings, ui
523520
524521 os << YAML::Key << " handle" << YAML::Value << device_.GetObjectInfo ((uint64_t )vk_command_buffer_);
525522 os << YAML::Key << " commandPool" << YAML::Value << device_.GetObjectInfo ((uint64_t )vk_command_pool_);
526- if (buffer_state_ == CommandBufferState:: kPending ) {
523+ if (WasSubmittedToQueue () ) {
527524 os << YAML::Key << " queue" << device_.GetObjectInfo ((uint64_t )submitted_queue_);
528525 os << YAML::Key << " fence" << device_.GetObjectInfo ((uint64_t )submitted_fence_);
529526 }
@@ -556,9 +553,10 @@ void CommandBuffer::DumpContents(YAML::Emitter& os, const Settings& settings, ui
556553 // If the markers indicated we are complete but the queue semaphore thinks
557554 // we aren't completed, dump everything. We don't know which command in the
558555 // command buffer is the problem.
559- if (cb_state == CommandBufferState::kSubmittedExecutionCompleted ) {
560- last_completed = 1 ;
556+ if (cb_state == CommandBufferState::kMaybeComplete ) {
557+ last_completed = 0 ;
561558 }
559+
562560 os << YAML::Key << " lastStartedCommand" << YAML::Value << last_started;
563561 os << YAML::Key << " lastCompletedCommand" << YAML::Value << last_completed;
564562
@@ -569,7 +567,7 @@ void CommandBuffer::DumpContents(YAML::Emitter& os, const Settings& settings, ui
569567 os << YAML::Key << " Commands" << YAML::Value << YAML::BeginSeq;
570568 for (const auto & command : tracker_.GetCommands ()) {
571569 auto command_name = Command::GetCommandName (command);
572- auto command_state = GetCommandState (cb_state, command);
570+ auto command_state = GetCommandState (cb_state, command, last_started, last_completed );
573571
574572 if (dump_cmds == DumpCommands::kRunning ) {
575573 if (command.id < last_completed || command.id > last_started) {
@@ -608,13 +606,13 @@ void CommandBuffer::DumpContents(YAML::Emitter& os, const Settings& settings, ui
608606 }
609607 os << YAML::EndMap;
610608 state.Print (command, os, device_.GetObjectInfoDB ());
611- if (command_state == CommandState::kCommandIncomplete ) {
609+ if (command_state == CommandState::kIncomplete ) {
612610 HandleIncompleteCommand (command, state);
613611 }
614612
615613 // To make this message more visible, we put it in a special
616614 // Command entry.
617- if (cb_state == CommandBufferState::kSubmittedExecutionIncomplete ) {
615+ if (cb_state == CommandBufferState::kIncomplete ) {
618616 if (command.id == GetLastCompleteCommand ()) {
619617 os << YAML::Key << " message" << YAML::Value << " '>>>>>>>>>>>>>> LAST COMPLETE COMMAND <<<<<<<<<<<<<<'" ;
620618 } else if (command.id == GetLastStartedCommand ()) {
0 commit comments