/* * Copyright (C) 2018 Intel Corporation * * SPDX-License-Identifier: MIT * */ #pragma once #include "runtime/helpers/properties_helper.h" #include #include #include #include namespace OCLRT { class MemoryManager; template struct TagNode; #pragma pack(1) class TimestampPacket { public: enum class DataIndex : uint32_t { ContextStart = 0, GlobalStart, ContextEnd, GlobalEnd, Max }; enum class WriteOperationType : uint32_t { BeforeWalker, AfterWalker }; bool canBeReleased() const { return data[static_cast(DataIndex::ContextEnd)] != 1 && data[static_cast(DataIndex::GlobalEnd)] != 1 && implicitDependenciesCount.load() == 0; } uint64_t pickAddressForDataWrite(DataIndex operationType) const { auto index = static_cast(operationType); return reinterpret_cast(&data[index]); } void initialize() { data = {{1, 1, 1, 1}}; implicitDependenciesCount.store(0); } void incImplicitDependenciesCount() { implicitDependenciesCount++; } uint64_t pickImplicitDependenciesCountWriteAddress() const { return reinterpret_cast(&implicitDependenciesCount); } protected: std::array(DataIndex::Max)> data = {{1, 1, 1, 1}}; std::atomic implicitDependenciesCount{0}; }; #pragma pack() static_assert(((static_cast(TimestampPacket::DataIndex::Max) + 1) * sizeof(uint32_t)) == sizeof(TimestampPacket), "This structure is consumed by GPU and has to follow specific restrictions for padding and size"); struct TimestmapPacketHelper { template static void programSemaphoreWithImplicitDependency(LinearStream &cmdStream, TimestampPacket ×tmapPacket) { using MI_ATOMIC = typename GfxFamily::MI_ATOMIC; auto compareAddress = timestmapPacket.pickAddressForDataWrite(TimestampPacket::DataIndex::ContextEnd); auto dependenciesCountAddress = timestmapPacket.pickImplicitDependenciesCountWriteAddress(); KernelCommandsHelper::programMiSemaphoreWait(cmdStream, compareAddress, 1); timestmapPacket.incImplicitDependenciesCount(); KernelCommandsHelper::programMiAtomic(cmdStream, dependenciesCountAddress, MI_ATOMIC::ATOMIC_OPCODES::ATOMIC_4B_DECREMENT, MI_ATOMIC::DATA_SIZE::DATA_SIZE_DWORD); } }; class TimestampPacketContainer : public NonCopyableOrMovableClass { public: using Node = TagNode; TimestampPacketContainer() = delete; TimestampPacketContainer(MemoryManager *memoryManager); ~TimestampPacketContainer(); const std::vector &peekNodes() const { return timestampPacketNodes; } void add(Node *timestampPacketNode); void swapNodes(TimestampPacketContainer ×tampPacketContainer); void assignAndIncrementNodesRefCounts(TimestampPacketContainer ×tampPacketContainer); void resolveDependencies(bool clearAllDependencies); void makeResident(CommandStreamReceiver &commandStreamReceiver); protected: std::vector timestampPacketNodes; MemoryManager *memoryManager = nullptr; }; } // namespace OCLRT