blob: d02fff0b1c662078af0542442304f98452114600 [file]
/* 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