2023-09-20 18:47:56 +08:00
/*
2025-01-24 23:00:11 +08:00
* Copyright ( C ) 2023 - 2025 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>
2024-07-19 23:15:04 +08:00
# include <mutex>
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 :
2024-12-16 19:01:27 +08:00
using ValueT = uint64_t ;
2024-02-28 20:46:21 +08:00
static constexpr size_t defaultAllocatorTagCount = 128 ;
2025-01-30 18:23:55 +08:00
static constexpr AllocationType getAllocationType ( ) { return deviceAlloc ? NEO : : AllocationType : : gpuTimestampDeviceBuffer : NEO : : AllocationType : : timestampPacketTagBuffer ; }
2024-02-28 20:46:21 +08:00
static constexpr TagNodeType getTagNodeType ( ) { return TagNodeType : : counter64b ; }
static constexpr size_t getSinglePacketSize ( ) { return sizeof ( uint64_t ) ; }
2024-12-16 19:01:27 +08:00
void initialize ( uint64_t initValue ) { data = initValue ; }
2024-02-28 20:46:21 +08:00
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-13 23:48:10 +08:00
static std : : shared_ptr < InOrderExecInfo > create ( TagNodeBase * deviceCounterNode , TagNodeBase * hostCounterNode , NEO : : Device & device , uint32_t partitionCount , bool regularCmdList ) ;
2024-10-16 00:32:10 +08:00
static std : : shared_ptr < InOrderExecInfo > createFromExternalAllocation ( NEO : : Device & device , NEO : : GraphicsAllocation * deviceAllocation , uint64_t deviceAddress , NEO : : GraphicsAllocation * hostAllocation ,
uint64_t * hostAddress , uint64_t counterValue , uint32_t devicePartitions , uint32_t hostPartitions ) ;
2023-09-27 22:02:30 +08:00
2024-09-20 22:53:27 +08:00
InOrderExecInfo ( TagNodeBase * deviceCounterNode , TagNodeBase * hostCounterNode , NEO : : Device & device , uint32_t partitionCount , 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-13 23:48:10 +08:00
NEO : : GraphicsAllocation * getHostCounterAllocation ( ) const ;
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 ; }
2024-03-13 23:48:10 +08:00
uint64_t getBaseHostGpuAddress ( ) const ;
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 ( ) ;
2024-04-12 02:55:27 +08:00
bool isExternalMemoryExecInfo ( ) const { return deviceCounterNode = = nullptr ; }
2024-04-25 23:08:55 +08:00
void setLastWaitedCounterValue ( uint64_t value ) {
2025-02-19 23:24:13 +08:00
if ( ! isExternalMemoryExecInfo ( ) ) {
lastWaitedCounterValue = std : : max ( value , lastWaitedCounterValue ) ;
}
2024-04-25 23:08:55 +08:00
}
bool isCounterAlreadyDone ( uint64_t waitValue ) const {
return lastWaitedCounterValue > = waitValue & & this - > allocationOffset = = 0u ;
}
2023-11-30 19:27:42 +08:00
2024-05-07 19:47:34 +08:00
NEO : : GraphicsAllocation * getExternalHostAllocation ( ) const { return externalHostAllocation ; }
2024-10-16 00:32:10 +08:00
NEO : : GraphicsAllocation * getExternalDeviceAllocation ( ) const { return externalDeviceAllocation ; }
2024-05-07 19:47:34 +08:00
2024-07-19 23:15:04 +08:00
void pushTempTimestampNode ( TagNodeBase * node , uint64_t value ) ;
void releaseNotUsedTempTimestampNodes ( bool forceReturn ) ;
2023-11-30 19:27:42 +08:00
protected :
2024-09-20 22:53:27 +08:00
void uploadToTbx ( TagNodeBase & node , size_t size ) ;
NEO : : Device & device ;
2024-02-28 20:46:21 +08:00
NEO : : TagNodeBase * deviceCounterNode = nullptr ;
2024-03-13 23:48:10 +08:00
NEO : : TagNodeBase * hostCounterNode = nullptr ;
2024-05-06 23:11:38 +08:00
NEO : : GraphicsAllocation * externalHostAllocation = nullptr ;
2024-10-15 00:37:26 +08:00
NEO : : GraphicsAllocation * externalDeviceAllocation = nullptr ;
2024-07-19 23:15:04 +08:00
std : : vector < std : : pair < NEO : : TagNodeBase * , uint64_t > > tempTimestampNodes ;
std : : mutex mutex ;
2023-11-30 19:27:42 +08:00
uint64_t counterValue = 0 ;
2024-04-25 23:08:55 +08:00
uint64_t lastWaitedCounterValue = 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 ;
2024-09-20 22:53:27 +08:00
bool isTbx = 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 ,
2024-12-27 18:40:01 +08:00
walker ,
2025-05-09 15:04:35 +08:00
pipeControl ,
xyCopyBlt ,
xyBlockCopyBlt ,
xyColorBlt ,
memSet
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 ) {
2024-03-11 20:37:03 +08:00
if ( skipPatching ) {
return ;
}
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 ;
2024-12-27 18:40:01 +08:00
case PatchCmdType : : pipeControl :
patchPipeControl ( appendCounterValue ) ;
break ;
2025-05-09 15:04:35 +08:00
case PatchCmdType : : xyCopyBlt :
case PatchCmdType : : xyBlockCopyBlt :
case PatchCmdType : : xyColorBlt :
case PatchCmdType : : memSet :
patchBlitterCommand ( appendCounterValue , patchCmdType ) ;
break ;
2023-09-22 19:18:43 +08:00
default :
UNRECOVERABLE_IF ( true ) ;
break ;
2023-09-20 18:47:56 +08:00
}
}
2024-03-11 20:37:03 +08:00
void updateInOrderExecInfo ( std : : shared_ptr < InOrderExecInfo > * inOrderExecInfo ) {
this - > inOrderExecInfo = * inOrderExecInfo ;
}
void setSkipPatching ( bool value ) {
skipPatching = value ;
}
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 ;
2024-03-11 20:37:03 +08:00
bool skipPatching = 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 ) ;
2025-05-09 15:04:35 +08:00
void patchBlitterCommand ( uint64_t appendCounterValue , PatchCmdType patchCmdType ) ;
2023-09-22 19:18:43 +08:00
2024-12-27 18:40:01 +08:00
void patchPipeControl ( uint64_t appendCounterValue ) {
auto pcCmd = reinterpret_cast < typename GfxFamily : : PIPE_CONTROL * > ( cmd1 ) ;
pcCmd - > setImmediateData ( static_cast < uint64_t > ( baseCounterValue + appendCounterValue ) ) ;
}
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