| 523 | } |
| 524 | |
| 525 | void AccessState::Update(const SyncAccessInfo& usage_info, const AttachmentAccess& attachment_access, ResourceUsageTagEx tag_ex, |
| 526 | SyncFlags flags) { |
| 527 | const VkPipelineStageFlagBits2 usage_stage = usage_info.stage_mask; |
| 528 | if (IsRead(usage_info.access_index)) { |
| 529 | // Mulitple outstanding reads may be of interest and do dependency chains independently |
| 530 | // However, for purposes of barrier tracking, only one read per pipeline stage matters |
| 531 | if (usage_stage & last_read_stages) { |
| 532 | const auto not_usage_stage = ~usage_stage; |
| 533 | for (auto& read_access : GetReads()) { |
| 534 | if (read_access.stage == usage_stage) { |
| 535 | read_access.Set(usage_stage, usage_info.access_index, attachment_access, tag_ex); |
| 536 | } else if (read_access.barriers & usage_stage) { |
| 537 | // If the current access is barriered to this stage, mark it as "known to happen after" |
| 538 | read_access.sync_stages |= usage_stage; |
| 539 | } else { |
| 540 | // If the current access is *NOT* barriered to this stage it needs to be cleared. |
| 541 | // Note: this is possible because semaphores can *clear* effective barriers, so the assumption |
| 542 | // that sync_stages is a subset of barriers may not apply. |
| 543 | read_access.sync_stages &= not_usage_stage; |
| 544 | } |
| 545 | } |
| 546 | } else { |
| 547 | for (auto& read_access : GetReads()) { |
| 548 | if (read_access.barriers & usage_stage) { |
| 549 | read_access.sync_stages |= usage_stage; |
| 550 | } |
| 551 | } |
| 552 | ReadState new_read_state; |
| 553 | new_read_state.Set(usage_stage, usage_info.access_index, attachment_access, tag_ex); |
| 554 | AddRead(new_read_state); |
| 555 | last_read_stages |= usage_stage; |
| 556 | } |
| 557 | |
| 558 | // Fragment shader reads come in two flavors, and we need to track if the one we're tracking is the special one. |
| 559 | if (usage_stage == VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT) { |
| 560 | // TODO Revisit re: multiple reads for a given stage |
| 561 | input_attachment_read = (usage_info.access_index == SYNC_FRAGMENT_SHADER_INPUT_ATTACHMENT_READ); |
| 562 | } |
| 563 | } else { |
| 564 | SetWrite(usage_info.access_index, attachment_access, tag_ex, flags); |
| 565 | } |
| 566 | UpdateFirst(tag_ex, usage_info, attachment_access, flags); |
| 567 | } |
| 568 | |
| 569 | HazardResult HazardResult::HazardVsPriorWrite(const AccessState* access_state, const SyncAccessInfo& usage_info, SyncHazard hazard, |
| 570 | const WriteState& prior_write) { |