2023-09-20 18:47:56 +08:00
/*
2024-01-13 00:27:50 +08:00
* Copyright ( C ) 2023 - 2024 Intel Corporation
2023-09-20 18:47:56 +08:00
*
* SPDX - License - Identifier : MIT
*
*/
# pragma once
2024-02-28 20:46:21 +08:00
# include "shared/source/helpers/common_types.h"
2023-09-27 22:02:30 +08:00
# include "shared/source/helpers/non_copyable_or_moveable.h"
2023-09-20 18:47:56 +08:00
# include "shared/source/helpers/ptr_math.h"
2024-02-28 20:46:21 +08:00
# include "shared/source/memory_manager/allocation_type.h"
2023-09-20 18:47:56 +08:00
# include <cstdint>
2023-10-03 17:34:45 +08:00
# include <memory>
2023-09-20 18:47:56 +08:00
# include <vector>
2023-09-27 22:02:30 +08:00
namespace NEO {
class GraphicsAllocation ;
class MemoryManager ;
2024-01-13 00:27:50 +08:00
class Device ;
2024-02-28 20:46:21 +08:00
class TagNodeBase ;
template < bool deviceAlloc >
class DeviceAllocNodeType {
public :
static constexpr size_t defaultAllocatorTagCount = 128 ;
static constexpr AllocationType getAllocationType ( ) { return deviceAlloc ? AllocationType : : timestampPacketTagBuffer : NEO : : AllocationType : : bufferHostMemory ; }
static constexpr TagNodeType getTagNodeType ( ) { return TagNodeType : : counter64b ; }
static constexpr size_t getSinglePacketSize ( ) { return sizeof ( uint64_t ) ; }
void initialize ( ) { data = 0 ; }
protected :
uint64_t data = { } ;
} ;
static_assert ( sizeof ( uint64_t ) = = sizeof ( DeviceAllocNodeType < true > ) , " This structure is consumed by GPU and has to follow specific restrictions for padding and size " ) ;
static_assert ( sizeof ( uint64_t ) = = sizeof ( DeviceAllocNodeType < false > ) , " This structure is consumed by GPU and has to follow specific restrictions for padding and size " ) ;
2023-09-27 22:02:30 +08:00
2023-11-30 19:27:42 +08:00
class InOrderExecInfo : public NEO : : NonCopyableClass {
public :
2023-09-27 22:02:30 +08:00
~ InOrderExecInfo ( ) ;
InOrderExecInfo ( ) = delete ;
2024-03-10 02:18:46 +08:00
static std : : shared_ptr < InOrderExecInfo > create ( TagNodeBase * deviceCounterNode , NEO : : Device & device , uint32_t partitionCount , bool regularCmdList ) ;
2024-01-13 00:27:50 +08:00
static std : : shared_ptr < InOrderExecInfo > createFromExternalAllocation ( NEO : : Device & device , uint64_t deviceAddress , uint64_t * hostAddress , uint64_t counterValue ) ;
2023-09-27 22:02:30 +08:00
2024-03-10 02:18:46 +08:00
InOrderExecInfo ( TagNodeBase * deviceCounterNode , NEO : : GraphicsAllocation * hostCounterAllocation , NEO : : MemoryManager & memoryManager , uint32_t partitionCount , uint32_t rootDeviceIndex ,
2024-02-28 20:46:21 +08:00
bool regularCmdList , bool atomicDeviceSignalling ) ;
2024-01-13 00:27:50 +08:00
2024-02-28 20:46:21 +08:00
NEO : : GraphicsAllocation * getDeviceCounterAllocation ( ) const ;
2024-03-10 02:18:46 +08:00
NEO : : GraphicsAllocation * getHostCounterAllocation ( ) const { return hostCounterAllocation ; }
2023-12-11 19:45:58 +08:00
uint64_t * getBaseHostAddress ( ) const { return hostAddress ; }
2024-01-13 00:27:50 +08:00
uint64_t getBaseDeviceAddress ( ) const { return deviceAddress ; }
2023-11-30 19:27:42 +08:00
uint64_t getCounterValue ( ) const { return counterValue ; }
void addCounterValue ( uint64_t addValue ) { counterValue + = addValue ; }
void resetCounterValue ( ) { counterValue = 0 ; }
uint64_t getRegularCmdListSubmissionCounter ( ) const { return regularCmdListSubmissionCounter ; }
void addRegularCmdListSubmissionCounter ( uint64_t addValue ) { regularCmdListSubmissionCounter + = addValue ; }
bool isRegularCmdList ( ) const { return regularCmdList ; }
2023-12-07 23:33:34 +08:00
bool isHostStorageDuplicated ( ) const { return duplicatedHostStorage ; }
2023-12-13 19:47:42 +08:00
bool isAtomicDeviceSignalling ( ) const { return atomicDeviceSignalling ; }
2023-11-30 19:27:42 +08:00
2023-12-01 21:20:13 +08:00
uint32_t getNumDevicePartitionsToWait ( ) const { return numDevicePartitionsToWait ; }
uint32_t getNumHostPartitionsToWait ( ) const { return numHostPartitionsToWait ; }
2024-02-28 00:06:51 +08:00
void setAllocationOffset ( uint32_t newOffset ) { allocationOffset = newOffset ; }
void initializeAllocationsFromHost ( ) ;
2023-12-11 19:45:58 +08:00
uint32_t getAllocationOffset ( ) const { return allocationOffset ; }
2023-11-30 19:27:42 +08:00
void reset ( ) ;
protected :
2023-09-27 22:02:30 +08:00
NEO : : MemoryManager & memoryManager ;
2024-02-28 20:46:21 +08:00
NEO : : TagNodeBase * deviceCounterNode = nullptr ;
2024-03-10 02:18:46 +08:00
NEO : : GraphicsAllocation * hostCounterAllocation = nullptr ;
2023-11-30 19:27:42 +08:00
uint64_t counterValue = 0 ;
2023-09-27 22:02:30 +08:00
uint64_t regularCmdListSubmissionCounter = 0 ;
2024-01-13 00:27:50 +08:00
uint64_t deviceAddress = 0 ;
2023-12-01 21:20:13 +08:00
uint64_t * hostAddress = nullptr ;
uint32_t numDevicePartitionsToWait = 0 ;
uint32_t numHostPartitionsToWait = 0 ;
2023-12-11 19:45:58 +08:00
uint32_t allocationOffset = 0 ;
2024-02-28 20:46:21 +08:00
uint32_t rootDeviceIndex = 0 ;
2023-11-30 19:27:42 +08:00
bool regularCmdList = false ;
2023-12-07 23:33:34 +08:00
bool duplicatedHostStorage = false ;
2023-12-13 19:47:42 +08:00
bool atomicDeviceSignalling = false ;
2023-09-27 22:02:30 +08:00
} ;
2023-09-29 21:47:43 +08:00
namespace InOrderPatchCommandHelpers {
inline uint64_t getAppendCounterValue ( const InOrderExecInfo & inOrderExecInfo ) {
2023-11-30 19:27:42 +08:00
if ( inOrderExecInfo . isRegularCmdList ( ) & & inOrderExecInfo . getRegularCmdListSubmissionCounter ( ) > 1 ) {
return inOrderExecInfo . getCounterValue ( ) * ( inOrderExecInfo . getRegularCmdListSubmissionCounter ( ) - 1 ) ;
2023-09-29 21:47:43 +08:00
}
return 0 ;
}
enum class PatchCmdType {
2023-12-14 00:09:52 +08:00
none ,
lri64b ,
sdi ,
semaphore ,
walker
2023-09-20 18:47:56 +08:00
} ;
template < typename GfxFamily >
2023-09-29 21:47:43 +08:00
struct PatchCmd {
2023-12-21 21:48:32 +08:00
PatchCmd ( std : : shared_ptr < InOrderExecInfo > * inOrderExecInfo , void * cmd1 , void * cmd2 , uint64_t baseCounterValue , PatchCmdType patchCmdType , bool deviceAtomicSignaling , bool duplicatedHostStorage )
: cmd1 ( cmd1 ) , cmd2 ( cmd2 ) , baseCounterValue ( baseCounterValue ) , patchCmdType ( patchCmdType ) , deviceAtomicSignaling ( deviceAtomicSignaling ) , duplicatedHostStorage ( duplicatedHostStorage ) {
2023-10-03 17:34:45 +08:00
if ( inOrderExecInfo ) {
this - > inOrderExecInfo = * inOrderExecInfo ;
}
}
2023-09-20 18:47:56 +08:00
2023-11-09 01:23:41 +08:00
void patch ( uint64_t appendCounterValue ) {
2023-09-29 21:47:43 +08:00
switch ( patchCmdType ) {
2023-12-14 00:09:52 +08:00
case PatchCmdType : : sdi :
2023-11-09 01:23:41 +08:00
patchSdi ( appendCounterValue ) ;
2023-09-22 19:18:43 +08:00
break ;
2023-12-14 00:09:52 +08:00
case PatchCmdType : : semaphore :
2023-11-09 01:23:41 +08:00
patchSemaphore ( appendCounterValue ) ;
2023-09-22 19:18:43 +08:00
break ;
2023-12-14 00:09:52 +08:00
case PatchCmdType : : walker :
2023-11-09 01:23:41 +08:00
patchComputeWalker ( appendCounterValue ) ;
break ;
2023-12-14 00:09:52 +08:00
case PatchCmdType : : lri64b :
2023-11-09 01:23:41 +08:00
patchLri64b ( appendCounterValue ) ;
2023-09-22 19:18:43 +08:00
break ;
default :
UNRECOVERABLE_IF ( true ) ;
break ;
2023-09-20 18:47:56 +08:00
}
}
2023-10-03 17:34:45 +08:00
bool isExternalDependency ( ) const { return inOrderExecInfo . get ( ) ; }
std : : shared_ptr < InOrderExecInfo > inOrderExecInfo ;
2023-11-09 01:23:41 +08:00
void * cmd1 = nullptr ;
void * cmd2 = nullptr ;
2023-09-20 18:47:56 +08:00
const uint64_t baseCounterValue = 0 ;
2023-12-14 00:09:52 +08:00
const PatchCmdType patchCmdType = PatchCmdType : : none ;
2023-12-21 21:48:32 +08:00
bool deviceAtomicSignaling = false ;
bool duplicatedHostStorage = false ;
2023-09-20 18:47:56 +08:00
protected :
2023-11-09 01:23:41 +08:00
void patchSdi ( uint64_t appendCounterValue ) {
auto sdiCmd = reinterpret_cast < typename GfxFamily : : MI_STORE_DATA_IMM * > ( cmd1 ) ;
sdiCmd - > setDataDword0 ( getLowPart ( baseCounterValue + appendCounterValue ) ) ;
sdiCmd - > setDataDword1 ( getHighPart ( baseCounterValue + appendCounterValue ) ) ;
2023-09-20 18:47:56 +08:00
}
2023-11-09 01:23:41 +08:00
void patchSemaphore ( uint64_t appendCounterValue ) {
2023-10-03 17:34:45 +08:00
if ( isExternalDependency ( ) ) {
2023-11-09 01:23:41 +08:00
appendCounterValue = InOrderPatchCommandHelpers : : getAppendCounterValue ( * inOrderExecInfo ) ;
if ( appendCounterValue = = 0 ) {
2023-10-03 17:34:45 +08:00
return ;
}
}
2023-11-09 01:23:41 +08:00
auto semaphoreCmd = reinterpret_cast < typename GfxFamily : : MI_SEMAPHORE_WAIT * > ( cmd1 ) ;
semaphoreCmd - > setSemaphoreDataDword ( static_cast < uint32_t > ( baseCounterValue + appendCounterValue ) ) ;
2023-09-20 18:47:56 +08:00
}
2023-12-21 21:16:43 +08:00
void patchComputeWalker ( uint64_t appendCounterValue ) ;
2023-09-22 19:18:43 +08:00
2023-11-09 01:23:41 +08:00
void patchLri64b ( uint64_t appendCounterValue ) {
if ( isExternalDependency ( ) ) {
appendCounterValue = InOrderPatchCommandHelpers : : getAppendCounterValue ( * inOrderExecInfo ) ;
if ( appendCounterValue = = 0 ) {
return ;
}
}
const uint64_t counterValue = baseCounterValue + appendCounterValue ;
auto lri1 = reinterpret_cast < typename GfxFamily : : MI_LOAD_REGISTER_IMM * > ( cmd1 ) ;
lri1 - > setDataDword ( getLowPart ( counterValue ) ) ;
auto lri2 = reinterpret_cast < typename GfxFamily : : MI_LOAD_REGISTER_IMM * > ( cmd2 ) ;
lri2 - > setDataDword ( getHighPart ( counterValue ) ) ;
}
2023-09-29 21:47:43 +08:00
PatchCmd ( ) = delete ;
2023-09-20 18:47:56 +08:00
} ;
2023-09-29 21:47:43 +08:00
} // namespace InOrderPatchCommandHelpers
2023-09-20 18:47:56 +08:00
template < typename GfxFamily >
2023-12-11 20:10:56 +08:00
using InOrderPatchCommandsContainer = std : : vector < NEO : : InOrderPatchCommandHelpers : : PatchCmd < GfxFamily > > ;
2023-09-20 18:47:56 +08:00
2023-12-11 20:10:56 +08:00
} // namespace NEO