| /* Copyright (c) 2026 The Khronos Group Inc. |
| * Copyright (c) 2026 Valve Corporation |
| * Copyright (c) 2026 LunarG, Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "state_tracker/event_state.h" |
| |
| bool EventSignalState::HasKnownEffect(const EventSignalState* prior_state) const { |
| // After a reset, later signal/reset commands define the event state |
| if (was_reset) { |
| return true; |
| } |
| // If the prior state ended unsignaled, this state cannot be a repeated |
| // signal and defines the event state |
| const bool is_prior_unsignaled = prior_state && !prior_state->signaled; |
| return is_prior_unsignaled; |
| } |
| |
| const EventSignalState* ResolveSecondarySignal(const EventSignalState* prior_state, const EventSignalState* secondary_state) { |
| if (secondary_state && secondary_state->HasKnownEffect(prior_state)) { |
| return secondary_state; |
| } |
| if (prior_state && prior_state->HasKnownEffect()) { |
| return prior_state; |
| } |
| return nullptr; |
| } |
| |
| EventSignalState ResolveEventSignal(const vvl::Event& event_state, const EventSignalState* local_signal_state, |
| const EventSignalState* cb_signal_state) { |
| EventSignalState state; |
| state.signaled = event_state.signaled; |
| state.was_reset = true; // the global event state is known (so HasKnownEffect works as expected) |
| state.signal_src_stage_mask = event_state.signal_src_stage_mask; |
| state.signal_dependency_info = event_state.signal_dependency_info; |
| state.last_signaling_command = event_state.last_signaling_command; |
| |
| const EventSignalState* prior_state = &state; |
| if (local_signal_state && local_signal_state->HasKnownEffect(prior_state)) { |
| state = *local_signal_state; |
| } |
| prior_state = local_signal_state ? local_signal_state : prior_state; |
| if (cb_signal_state && cb_signal_state->HasKnownEffect(prior_state)) { |
| state = *cb_signal_state; |
| } |
| return state; |
| } |
| |
| void UpdateEventSignalStates(EventSignalStateMap& accumulated_states, const EventSignalStateMap& recorded_states) { |
| for (const auto& [event, recorded_state] : recorded_states) { |
| EventSignalState& accumulated_state = accumulated_states[event]; |
| |
| const bool keep_accumulated_state = accumulated_state.signaled && !recorded_state.was_reset; |
| if (keep_accumulated_state) { |
| continue; |
| } |
| |
| const bool was_reset = accumulated_state.was_reset; |
| accumulated_state = recorded_state; |
| accumulated_state.was_reset |= was_reset; |
| } |
| } |
| |
| #ifdef VK_USE_PLATFORM_METAL_EXT |
| static bool GetMetalExport(const VkEventCreateInfo* info) { |
| bool retval = false; |
| auto export_metal_object_info = vku::FindStructInPNextChain<VkExportMetalObjectCreateInfoEXT>(info->pNext); |
| while (export_metal_object_info) { |
| if (export_metal_object_info->exportObjectType == VK_EXPORT_METAL_OBJECT_TYPE_METAL_SHARED_EVENT_BIT_EXT) { |
| retval = true; |
| break; |
| } |
| export_metal_object_info = vku::FindStructInPNextChain<VkExportMetalObjectCreateInfoEXT>(export_metal_object_info->pNext); |
| } |
| return retval; |
| } |
| #endif // VK_USE_PLATFORM_METAL_EXT |
| |
| namespace vvl { |
| Event::Event(VkEvent handle, const VkEventCreateInfo* create_info) |
| : StateObject(handle, kVulkanObjectTypeEvent), |
| flags(create_info->flags) |
| #ifdef VK_USE_PLATFORM_METAL_EXT |
| , |
| metal_event_export(GetMetalExport(create_info)) |
| #endif // VK_USE_PLATFORM_METAL_EXT |
| { |
| } |
| } // namespace vvl |