2017-12-21 07:45:38 +08:00
/*
2022-01-19 23:18:21 +08:00
* Copyright ( C ) 2018 - 2022 Intel Corporation
2017-12-21 07:45:38 +08:00
*
2018-09-19 04:40:46 +08:00
* SPDX - License - Identifier : MIT
2017-12-21 07:45:38 +08:00
*
*/
2020-02-23 05:50:57 +08:00
# include "opencl/source/command_queue/command_queue.h"
2019-02-27 18:39:32 +08:00
2020-02-24 05:44:01 +08:00
# include "shared/source/command_stream/command_stream_receiver.h"
# include "shared/source/helpers/aligned_memory.h"
# include "shared/source/helpers/array_count.h"
# include "shared/source/helpers/engine_node_helper.h"
# include "shared/source/helpers/get_info.h"
# include "shared/source/helpers/ptr_math.h"
# include "shared/source/helpers/string.h"
# include "shared/source/helpers/timestamp_packet.h"
# include "shared/source/memory_manager/internal_allocation_storage.h"
2021-10-13 21:30:45 +08:00
# include "shared/source/os_interface/hw_info_config.h"
2020-02-24 05:44:01 +08:00
# include "shared/source/os_interface/os_context.h"
# include "shared/source/utilities/api_intercept.h"
# include "shared/source/utilities/tag_allocator.h"
2020-02-24 17:22:30 +08:00
2020-02-23 05:50:57 +08:00
# include "opencl/source/built_ins/builtins_dispatch_builder.h"
2020-03-20 18:15:25 +08:00
# include "opencl/source/cl_device/cl_device.h"
2020-02-23 05:50:57 +08:00
# include "opencl/source/context/context.h"
# include "opencl/source/event/event_builder.h"
# include "opencl/source/event/user_event.h"
# include "opencl/source/gtpin/gtpin_notify.h"
2021-02-12 20:25:51 +08:00
# include "opencl/source/helpers/cl_hw_helper.h"
2020-02-23 05:50:57 +08:00
# include "opencl/source/helpers/convert_color.h"
# include "opencl/source/helpers/hardware_commands_helper.h"
# include "opencl/source/helpers/mipmap.h"
# include "opencl/source/helpers/queue_helpers.h"
# include "opencl/source/mem_obj/buffer.h"
# include "opencl/source/mem_obj/image.h"
2020-08-26 21:44:12 +08:00
# include "opencl/source/program/printf_handler.h"
2019-02-27 18:39:32 +08:00
# include "CL/cl_ext.h"
2020-11-16 19:43:03 +08:00
# include <limits>
2017-12-21 07:45:38 +08:00
# include <map>
2019-03-26 18:59:46 +08:00
namespace NEO {
2017-12-21 07:45:38 +08:00
// Global table of create functions
CommandQueueCreateFunc commandQueueFactory [ IGFX_MAX_CORE ] = { } ;
CommandQueue * CommandQueue : : create ( Context * context ,
2020-01-14 21:32:11 +08:00
ClDevice * device ,
2017-12-21 07:45:38 +08:00
const cl_queue_properties * properties ,
2020-01-21 16:35:12 +08:00
bool internalUsage ,
2017-12-21 07:45:38 +08:00
cl_int & retVal ) {
retVal = CL_SUCCESS ;
auto funcCreate = commandQueueFactory [ device - > getRenderCoreFamily ( ) ] ;
DEBUG_BREAK_IF ( nullptr = = funcCreate ) ;
2020-01-21 16:35:12 +08:00
return funcCreate ( context , device , properties , internalUsage ) ;
2017-12-21 07:45:38 +08:00
}
2021-07-02 19:34:07 +08:00
CommandQueue : : CommandQueue ( Context * context , ClDevice * device , const cl_queue_properties * properties , bool internalUsage )
2020-01-14 21:32:11 +08:00
: context ( context ) , device ( device ) {
2017-12-21 07:45:38 +08:00
if ( context ) {
context - > incRefInternal ( ) ;
}
2018-04-26 16:01:01 +08:00
2017-12-21 07:45:38 +08:00
commandQueueProperties = getCmdQueueProperties < cl_command_queue_properties > ( properties ) ;
flushStamp . reset ( new FlushStampTracker ( true ) ) ;
2018-10-03 05:37:30 +08:00
2018-11-22 20:57:10 +08:00
if ( device ) {
2021-07-20 00:18:52 +08:00
auto & hwInfo = device - > getHardwareInfo ( ) ;
2021-03-03 22:26:16 +08:00
auto & hwHelper = HwHelper : : get ( hwInfo . platform . eRenderCoreFamily ) ;
2021-10-28 04:22:31 +08:00
auto hwInfoConfig = HwInfoConfig : : get ( hwInfo . platform . eProductFamily ) ;
2021-03-03 22:26:16 +08:00
2019-07-15 20:28:09 +08:00
gpgpuEngine = & device - > getDefaultEngine ( ) ;
2021-11-12 19:02:17 +08:00
2021-03-19 17:44:36 +08:00
UNRECOVERABLE_IF ( gpgpuEngine - > getEngineType ( ) > = aub_stream : : EngineType : : NUM_ENGINES ) ;
2021-10-28 04:22:31 +08:00
bool bcsAllowed = hwInfoConfig - > isBlitterFullySupported ( hwInfo ) & &
2021-03-03 22:26:16 +08:00
hwHelper . isSubDeviceEngineSupported ( hwInfo , device - > getDeviceBitfield ( ) , aub_stream : : EngineType : : ENGINE_BCS ) ;
if ( bcsAllowed | | gpgpuEngine - > commandStreamReceiver - > peekTimestampPacketWriteEnabled ( ) ) {
2018-11-27 20:07:41 +08:00
timestampPacketContainer = std : : make_unique < TimestampPacketContainer > ( ) ;
2021-06-15 00:57:09 +08:00
deferredTimestampPackets = std : : make_unique < TimestampPacketContainer > ( ) ;
2018-11-22 20:57:10 +08:00
}
2021-03-03 22:26:16 +08:00
if ( bcsAllowed ) {
2021-08-31 19:49:04 +08:00
auto & neoDevice = device - > getNearestGenericSubDevice ( 0 ) - > getDevice ( ) ;
2021-07-02 19:34:07 +08:00
auto & selectorCopyEngine = neoDevice . getSelectorCopyEngine ( ) ;
2021-08-17 22:15:49 +08:00
auto bcsEngineType = EngineHelpers : : getBcsEngineType ( hwInfo , device - > getDeviceBitfield ( ) , selectorCopyEngine , internalUsage ) ;
2021-09-25 00:32:20 +08:00
bcsEngines [ EngineHelpers : : getBcsIndex ( bcsEngineType ) ] = neoDevice . tryGetEngine ( bcsEngineType , EngineUsage : : Regular ) ;
2021-11-04 22:48:13 +08:00
bcsEngineTypes . push_back ( bcsEngineType ) ;
2019-07-16 15:23:02 +08:00
}
2018-10-03 05:37:30 +08:00
}
2018-11-29 18:39:10 +08:00
2020-05-27 23:12:32 +08:00
storeProperties ( properties ) ;
2018-12-06 16:21:28 +08:00
processProperties ( properties ) ;
2017-12-21 07:45:38 +08:00
}
CommandQueue : : ~ CommandQueue ( ) {
if ( virtualEvent ) {
UNRECOVERABLE_IF ( this - > virtualEvent - > getCommandQueue ( ) ! = this & & this - > virtualEvent - > getCommandQueue ( ) ! = nullptr ) ;
virtualEvent - > decRefInternal ( ) ;
}
if ( device ) {
2019-11-24 21:50:41 +08:00
auto storageForAllocation = gpgpuEngine - > commandStreamReceiver - > getInternalAllocationStorage ( ) ;
2017-12-21 07:45:38 +08:00
2018-11-09 00:22:21 +08:00
if ( commandStream ) {
2018-10-24 20:25:04 +08:00
storageForAllocation - > storeAllocation ( std : : unique_ptr < GraphicsAllocation > ( commandStream - > getGraphicsAllocation ( ) ) , REUSABLE_ALLOCATION ) ;
2017-12-21 07:45:38 +08:00
}
delete commandStream ;
if ( this - > perfCountersEnabled ) {
device - > getPerformanceCounters ( ) - > shutdown ( ) ;
}
2021-07-02 19:34:07 +08:00
2021-09-25 00:32:20 +08:00
if ( auto mainBcs = bcsEngines [ 0 ] ; mainBcs ! = nullptr ) {
2021-08-31 19:49:04 +08:00
auto & selectorCopyEngine = device - > getNearestGenericSubDevice ( 0 ) - > getSelectorCopyEngine ( ) ;
2021-09-25 00:32:20 +08:00
EngineHelpers : : releaseBcsEngineType ( mainBcs - > getEngineType ( ) , selectorCopyEngine ) ;
2021-07-02 19:34:07 +08:00
}
2017-12-21 07:45:38 +08:00
}
2018-12-13 23:24:42 +08:00
timestampPacketContainer . reset ( ) ;
2018-01-05 18:33:30 +08:00
//for normal queue, decrement ref count on context
//special queue is owned by context so ref count doesn't have to be decremented
if ( context & & ! isSpecialCommandQueue ) {
2017-12-21 07:45:38 +08:00
context - > decRefInternal ( ) ;
}
2021-08-31 23:44:43 +08:00
gtpinRemoveCommandQueue ( this ) ;
2017-12-21 07:45:38 +08:00
}
2019-07-15 20:28:09 +08:00
CommandStreamReceiver & CommandQueue : : getGpgpuCommandStreamReceiver ( ) const {
return * gpgpuEngine - > commandStreamReceiver ;
2018-11-22 20:57:10 +08:00
}
2021-09-21 21:22:36 +08:00
CommandStreamReceiver * CommandQueue : : getBcsCommandStreamReceiver ( aub_stream : : EngineType bcsEngineType ) const {
2021-09-25 00:32:20 +08:00
const EngineControl * engine = this - > bcsEngines [ EngineHelpers : : getBcsIndex ( bcsEngineType ) ] ;
if ( engine = = nullptr ) {
return nullptr ;
} else {
return engine - > commandStreamReceiver ;
2019-07-16 15:23:02 +08:00
}
}
2021-11-04 22:48:13 +08:00
CommandStreamReceiver * CommandQueue : : getBcsForAuxTranslation ( ) const {
2021-09-25 00:32:20 +08:00
for ( const EngineControl * engine : this - > bcsEngines ) {
if ( engine ! = nullptr ) {
return engine - > commandStreamReceiver ;
}
2021-08-26 00:03:15 +08:00
}
return nullptr ;
}
2021-09-07 01:04:14 +08:00
CommandStreamReceiver & CommandQueue : : selectCsrForBuiltinOperation ( const CsrSelectionArgs & args ) const {
2021-10-07 01:40:30 +08:00
if ( isCopyOnly ) {
2021-11-04 22:48:13 +08:00
return * getBcsCommandStreamReceiver ( bcsEngineTypes [ 0 ] ) ;
2021-10-07 01:40:30 +08:00
}
if ( ! blitEnqueueAllowed ( args ) ) {
2021-09-07 01:04:14 +08:00
return getGpgpuCommandStreamReceiver ( ) ;
}
2021-10-07 01:40:30 +08:00
bool preferBcs = true ;
aub_stream : : EngineType preferredBcsEngineType = aub_stream : : EngineType : : NUM_ENGINES ;
switch ( args . direction ) {
case TransferDirection : : LocalToLocal : {
const auto & clHwHelper = ClHwHelper : : get ( device - > getHardwareInfo ( ) . platform . eRenderCoreFamily ) ;
preferBcs = clHwHelper . preferBlitterForLocalToLocalTransfers ( ) ;
if ( auto flag = DebugManager . flags . PreferCopyEngineForCopyBufferToBuffer . get ( ) ; flag ! = - 1 ) {
preferBcs = static_cast < bool > ( flag ) ;
}
if ( preferBcs ) {
preferredBcsEngineType = aub_stream : : EngineType : : ENGINE_BCS ;
}
break ;
}
case TransferDirection : : HostToHost :
case TransferDirection : : HostToLocal :
case TransferDirection : : LocalToHost : {
preferBcs = true ;
2022-03-01 19:24:30 +08:00
auto preferredBCSType = true ;
if ( DebugManager . flags . AssignBCSAtEnqueue . get ( ) ! = - 1 ) {
preferredBCSType = DebugManager . flags . AssignBCSAtEnqueue . get ( ) ;
}
if ( preferredBCSType ) {
preferredBcsEngineType = EngineHelpers : : getBcsEngineType ( device - > getHardwareInfo ( ) , device - > getDeviceBitfield ( ) ,
device - > getSelectorCopyEngine ( ) , false ) ;
}
2021-10-07 01:40:30 +08:00
break ;
}
default :
UNRECOVERABLE_IF ( true ) ;
}
CommandStreamReceiver * selectedCsr = nullptr ;
if ( preferBcs ) {
2022-03-01 19:24:30 +08:00
auto assignBCS = true ;
if ( DebugManager . flags . AssignBCSAtEnqueue . get ( ) ! = - 1 ) {
assignBCS = DebugManager . flags . AssignBCSAtEnqueue . get ( ) ;
}
if ( assignBCS ) {
selectedCsr = getBcsCommandStreamReceiver ( preferredBcsEngineType ) ;
}
2021-11-04 22:48:13 +08:00
if ( selectedCsr = = nullptr & & ! bcsEngineTypes . empty ( ) ) {
selectedCsr = getBcsCommandStreamReceiver ( bcsEngineTypes [ 0 ] ) ;
2021-10-07 01:40:30 +08:00
}
}
if ( selectedCsr = = nullptr ) {
selectedCsr = & getGpgpuCommandStreamReceiver ( ) ;
}
UNRECOVERABLE_IF ( selectedCsr = = nullptr ) ;
return * selectedCsr ;
2021-09-07 01:04:14 +08:00
}
2020-01-14 21:32:11 +08:00
Device & CommandQueue : : getDevice ( ) const noexcept {
return device - > getDevice ( ) ;
}
2017-12-21 07:45:38 +08:00
uint32_t CommandQueue : : getHwTag ( ) const {
uint32_t tag = * getHwTagAddress ( ) ;
return tag ;
}
volatile uint32_t * CommandQueue : : getHwTagAddress ( ) const {
2019-07-15 20:28:09 +08:00
return getGpgpuCommandStreamReceiver ( ) . getTagAddress ( ) ;
2017-12-21 07:45:38 +08:00
}
2021-08-27 00:38:39 +08:00
bool CommandQueue : : isCompleted ( uint32_t gpgpuTaskCount , CopyEngineState bcsState ) const {
2021-10-13 06:08:25 +08:00
DEBUG_BREAK_IF ( getHwTag ( ) = = CompletionStamp : : notReady ) ;
2020-06-26 17:21:07 +08:00
2021-10-13 06:08:25 +08:00
if ( getGpgpuCommandStreamReceiver ( ) . testTaskCountReady ( getHwTagAddress ( ) , gpgpuTaskCount ) ) {
2021-08-27 00:38:39 +08:00
if ( bcsState . isValid ( ) ) {
2021-09-18 01:09:06 +08:00
return * getBcsCommandStreamReceiver ( bcsState . engineType ) - > getTagAddress ( ) > = peekBcsTaskCount ( bcsState . engineType ) ;
2020-06-26 17:21:07 +08:00
}
return true ;
}
return false ;
2017-12-21 07:45:38 +08:00
}
2022-02-22 20:51:29 +08:00
WaitStatus CommandQueue : : waitUntilComplete ( uint32_t gpgpuTaskCountToWait , Range < CopyEngineState > copyEnginesToWait , FlushStamp flushStampToWait , bool useQuickKmdSleep , bool cleanTemporaryAllocationList , bool skipWait ) {
2017-12-21 07:45:38 +08:00
WAIT_ENTER ( )
2022-02-22 20:51:29 +08:00
WaitStatus waitStatus { WaitStatus : : Ready } ;
2020-06-25 17:35:29 +08:00
DBG_LOG ( LogTaskCounts , __FUNCTION__ , " Waiting for taskCount: " , gpgpuTaskCountToWait ) ;
2017-12-21 07:45:38 +08:00
DBG_LOG ( LogTaskCounts , __FUNCTION__ , " Line: " , __LINE__ , " Current taskCount: " , getHwTag ( ) ) ;
2021-12-09 19:59:52 +08:00
if ( ! skipWait ) {
bool forcePowerSavingMode = this - > throttle = = QueueThrottle : : LOW ;
2018-11-16 19:46:49 +08:00
2022-02-22 20:51:29 +08:00
waitStatus = getGpgpuCommandStreamReceiver ( ) . waitForTaskCountWithKmdNotifyFallback ( gpgpuTaskCountToWait ,
flushStampToWait ,
useQuickKmdSleep ,
forcePowerSavingMode ) ;
if ( waitStatus = = WaitStatus : : GpuHang ) {
return WaitStatus : : GpuHang ;
}
2021-12-09 19:59:52 +08:00
DEBUG_BREAK_IF ( getHwTag ( ) < gpgpuTaskCountToWait ) ;
2019-07-15 17:01:32 +08:00
2021-12-09 19:59:52 +08:00
if ( gtpinIsGTPinInitialized ( ) ) {
gtpinNotifyTaskCompletion ( gpgpuTaskCountToWait ) ;
}
2021-12-27 18:43:20 +08:00
}
2020-02-19 23:32:40 +08:00
2021-12-27 18:43:20 +08:00
for ( const CopyEngineState & copyEngine : copyEnginesToWait ) {
auto bcsCsr = getBcsCommandStreamReceiver ( copyEngine . engineType ) ;
2019-07-12 20:48:52 +08:00
2022-02-22 20:51:29 +08:00
waitStatus = bcsCsr - > waitForTaskCountWithKmdNotifyFallback ( copyEngine . taskCount , 0 , false , false ) ;
if ( waitStatus = = WaitStatus : : GpuHang ) {
return WaitStatus : : GpuHang ;
}
waitStatus = bcsCsr - > waitForTaskCountAndCleanTemporaryAllocationList ( copyEngine . taskCount ) ;
if ( waitStatus = = WaitStatus : : GpuHang ) {
return WaitStatus : : GpuHang ;
}
2021-10-21 07:29:53 +08:00
}
2019-11-05 19:55:13 +08:00
2022-02-22 20:51:29 +08:00
waitStatus = cleanTemporaryAllocationList
? getGpgpuCommandStreamReceiver ( ) . waitForTaskCountAndCleanTemporaryAllocationList ( gpgpuTaskCountToWait )
: getGpgpuCommandStreamReceiver ( ) . waitForTaskCount ( gpgpuTaskCountToWait ) ;
2017-12-21 07:45:38 +08:00
WAIT_LEAVE ( )
2022-02-22 20:51:29 +08:00
return waitStatus ;
2017-12-21 07:45:38 +08:00
}
bool CommandQueue : : isQueueBlocked ( ) {
TakeOwnershipWrapper < CommandQueue > takeOwnershipWrapper ( * this ) ;
//check if we have user event and if so, if it is in blocked state.
if ( this - > virtualEvent ) {
2019-07-09 00:07:46 +08:00
auto executionStatus = this - > virtualEvent - > peekExecutionStatus ( ) ;
if ( executionStatus < = CL_SUBMITTED ) {
2017-12-21 07:45:38 +08:00
UNRECOVERABLE_IF ( this - > virtualEvent = = nullptr ) ;
2019-07-09 00:07:46 +08:00
if ( this - > virtualEvent - > isStatusCompletedByTermination ( executionStatus ) = = false ) {
2017-12-21 07:45:38 +08:00
taskCount = this - > virtualEvent - > peekTaskCount ( ) ;
flushStamp - > setStamp ( this - > virtualEvent - > flushStamp - > peekStamp ( ) ) ;
taskLevel = this - > virtualEvent - > taskLevel ;
// If this isn't an OOQ, update the taskLevel for the queue
if ( ! isOOQEnabled ( ) ) {
taskLevel + + ;
}
} else {
//at this point we may reset queue TaskCount, since all command previous to this were aborted
taskCount = 0 ;
flushStamp - > setStamp ( 0 ) ;
2019-07-15 20:28:09 +08:00
taskLevel = getGpgpuCommandStreamReceiver ( ) . peekTaskLevel ( ) ;
2017-12-21 07:45:38 +08:00
}
2019-12-10 23:26:35 +08:00
FileLoggerInstance ( ) . log ( DebugManager . flags . EventsDebugEnable . get ( ) , " isQueueBlocked taskLevel change from " , taskLevel , " to new from virtualEvent " , this - > virtualEvent , " new tasklevel " , this - > virtualEvent - > taskLevel . load ( ) ) ;
2017-12-21 07:45:38 +08:00
//close the access to virtual event, driver added only 1 ref count.
this - > virtualEvent - > decRefInternal ( ) ;
this - > virtualEvent = nullptr ;
return false ;
}
return true ;
}
return false ;
}
cl_int CommandQueue : : getCommandQueueInfo ( cl_command_queue_info paramName ,
size_t paramValueSize ,
void * paramValue ,
size_t * paramValueSizeRet ) {
2022-01-24 23:01:40 +08:00
return getQueueInfo ( this , paramName , paramValueSize , paramValue , paramValueSizeRet ) ;
2017-12-21 07:45:38 +08:00
}
uint32_t CommandQueue : : getTaskLevelFromWaitList ( uint32_t taskLevel ,
cl_uint numEventsInWaitList ,
const cl_event * eventWaitList ) {
for ( auto iEvent = 0u ; iEvent < numEventsInWaitList ; + + iEvent ) {
auto pEvent = ( Event * ) ( eventWaitList [ iEvent ] ) ;
uint32_t eventTaskLevel = pEvent - > taskLevel ;
taskLevel = std : : max ( taskLevel , eventTaskLevel ) ;
}
return taskLevel ;
}
LinearStream & CommandQueue : : getCS ( size_t minRequiredSize ) {
DEBUG_BREAK_IF ( nullptr = = device ) ;
if ( ! commandStream ) {
commandStream = new LinearStream ( nullptr ) ;
}
minRequiredSize + = CSRequirements : : minCommandQueueCommandStreamSize ;
2019-02-20 17:31:32 +08:00
constexpr static auto additionalAllocationSize = CSRequirements : : minCommandQueueCommandStreamSize + CSRequirements : : csOverfetchSize ;
2019-07-15 20:28:09 +08:00
getGpgpuCommandStreamReceiver ( ) . ensureCommandBufferAllocation ( * commandStream , minRequiredSize , additionalAllocationSize ) ;
2017-12-21 07:45:38 +08:00
return * commandStream ;
}
cl_int CommandQueue : : enqueueAcquireSharedObjects ( cl_uint numObjects , const cl_mem * memObjects , cl_uint numEventsInWaitList , const cl_event * eventWaitList , cl_event * oclEvent , cl_uint cmdType ) {
2018-01-18 00:02:08 +08:00
if ( ( memObjects = = nullptr & & numObjects ! = 0 ) | | ( memObjects ! = nullptr & & numObjects = = 0 ) ) {
return CL_INVALID_VALUE ;
}
2017-12-21 07:45:38 +08:00
for ( unsigned int object = 0 ; object < numObjects ; object + + ) {
2018-01-18 00:02:08 +08:00
auto memObject = castToObject < MemObj > ( memObjects [ object ] ) ;
if ( memObject = = nullptr | | memObject - > peekSharingHandler ( ) = = nullptr ) {
return CL_INVALID_MEM_OBJECT ;
}
2020-05-25 21:41:13 +08:00
int result = memObject - > peekSharingHandler ( ) - > acquire ( memObject , getDevice ( ) . getRootDeviceIndex ( ) ) ;
2018-04-19 20:11:45 +08:00
if ( result ! = CL_SUCCESS ) {
return result ;
}
2017-12-21 07:45:38 +08:00
memObject - > acquireCount + + ;
}
auto status = enqueueMarkerWithWaitList (
numEventsInWaitList ,
eventWaitList ,
oclEvent ) ;
if ( oclEvent ) {
castToObjectOrAbort < Event > ( * oclEvent ) - > setCmdType ( cmdType ) ;
}
return status ;
}
cl_int CommandQueue : : enqueueReleaseSharedObjects ( cl_uint numObjects , const cl_mem * memObjects , cl_uint numEventsInWaitList , const cl_event * eventWaitList , cl_event * oclEvent , cl_uint cmdType ) {
2018-01-18 00:02:08 +08:00
if ( ( memObjects = = nullptr & & numObjects ! = 0 ) | | ( memObjects ! = nullptr & & numObjects = = 0 ) ) {
return CL_INVALID_VALUE ;
}
2017-12-21 07:45:38 +08:00
for ( unsigned int object = 0 ; object < numObjects ; object + + ) {
2018-01-18 00:02:08 +08:00
auto memObject = castToObject < MemObj > ( memObjects [ object ] ) ;
if ( memObject = = nullptr | | memObject - > peekSharingHandler ( ) = = nullptr ) {
return CL_INVALID_MEM_OBJECT ;
}
2020-05-18 20:21:14 +08:00
memObject - > peekSharingHandler ( ) - > release ( memObject , getDevice ( ) . getRootDeviceIndex ( ) ) ;
2017-12-21 07:45:38 +08:00
DEBUG_BREAK_IF ( memObject - > acquireCount < = 0 ) ;
memObject - > acquireCount - - ;
}
auto status = enqueueMarkerWithWaitList (
numEventsInWaitList ,
eventWaitList ,
oclEvent ) ;
if ( oclEvent ) {
castToObjectOrAbort < Event > ( * oclEvent ) - > setCmdType ( cmdType ) ;
}
return status ;
}
2020-08-26 17:26:44 +08:00
void CommandQueue : : updateFromCompletionStamp ( const CompletionStamp & completionStamp , Event * outEvent ) {
2017-12-22 23:05:10 +08:00
DEBUG_BREAK_IF ( this - > taskLevel > completionStamp . taskLevel ) ;
DEBUG_BREAK_IF ( this - > taskCount > completionStamp . taskCount ) ;
2020-06-16 19:19:11 +08:00
if ( completionStamp . taskCount ! = CompletionStamp : : notReady ) {
2018-01-05 19:07:47 +08:00
taskCount = completionStamp . taskCount ;
}
2017-12-21 07:45:38 +08:00
flushStamp - > setStamp ( completionStamp . flushStamp ) ;
this - > taskLevel = completionStamp . taskLevel ;
2020-08-26 17:26:44 +08:00
if ( outEvent ) {
2021-08-27 00:38:39 +08:00
outEvent - > updateCompletionStamp ( completionStamp . taskCount , outEvent - > peekBcsTaskCountFromCommandQueue ( ) , completionStamp . taskLevel , completionStamp . flushStamp ) ;
2020-08-26 17:26:44 +08:00
FileLoggerInstance ( ) . log ( DebugManager . flags . EventsDebugEnable . get ( ) , " updateCompletionStamp Event " , outEvent , " taskLevel " , outEvent - > taskLevel . load ( ) ) ;
}
2017-12-21 07:45:38 +08:00
}
2019-12-19 19:58:02 +08:00
bool CommandQueue : : setPerfCountersEnabled ( ) {
2017-12-21 07:45:38 +08:00
DEBUG_BREAK_IF ( device = = nullptr ) ;
2019-12-19 19:58:02 +08:00
2017-12-21 07:45:38 +08:00
auto perfCounters = device - > getPerformanceCounters ( ) ;
2020-01-13 20:15:03 +08:00
bool isCcsEngine = EngineHelpers : : isCcs ( getGpgpuEngine ( ) . osContext - > getEngineType ( ) ) ;
2019-05-20 17:19:27 +08:00
2019-12-19 19:58:02 +08:00
perfCountersEnabled = perfCounters - > enable ( isCcsEngine ) ;
if ( ! perfCountersEnabled ) {
2019-05-20 17:19:27 +08:00
perfCounters - > shutdown ( ) ;
2017-12-21 07:45:38 +08:00
}
2019-05-20 17:19:27 +08:00
2019-12-19 19:58:02 +08:00
return perfCountersEnabled ;
}
2017-12-21 07:45:38 +08:00
PerformanceCounters * CommandQueue : : getPerfCounters ( ) {
return device - > getPerformanceCounters ( ) ;
}
2018-02-09 05:59:03 +08:00
cl_int CommandQueue : : enqueueWriteMemObjForUnmap ( MemObj * memObj , void * mappedPtr , EventsRequest & eventsRequest ) {
2018-02-18 05:26:28 +08:00
cl_int retVal = CL_SUCCESS ;
MapInfo unmapInfo ;
if ( ! memObj - > findMappedPtr ( mappedPtr , unmapInfo ) ) {
return CL_INVALID_VALUE ;
}
if ( ! unmapInfo . readOnly ) {
2020-07-23 20:52:32 +08:00
memObj - > getMapAllocation ( getDevice ( ) . getRootDeviceIndex ( ) ) - > setAubWritable ( true , GraphicsAllocation : : defaultBank ) ;
memObj - > getMapAllocation ( getDevice ( ) . getRootDeviceIndex ( ) ) - > setTbxWritable ( true , GraphicsAllocation : : defaultBank ) ;
2019-11-28 14:58:10 +08:00
2018-02-18 05:26:28 +08:00
if ( memObj - > peekClMemObjType ( ) = = CL_MEM_OBJECT_BUFFER ) {
auto buffer = castToObject < Buffer > ( memObj ) ;
2019-11-28 14:58:10 +08:00
2020-07-23 20:52:32 +08:00
retVal = enqueueWriteBuffer ( buffer , CL_FALSE , unmapInfo . offset [ 0 ] , unmapInfo . size [ 0 ] , mappedPtr , memObj - > getMapAllocation ( getDevice ( ) . getRootDeviceIndex ( ) ) ,
2018-02-18 05:26:28 +08:00
eventsRequest . numEventsInWaitList , eventsRequest . eventWaitList , eventsRequest . outEvent ) ;
2018-02-01 20:40:30 +08:00
} else {
2018-04-04 15:29:48 +08:00
auto image = castToObjectOrAbort < Image > ( memObj ) ;
size_t writeOrigin [ 4 ] = { unmapInfo . offset [ 0 ] , unmapInfo . offset [ 1 ] , unmapInfo . offset [ 2 ] , 0 } ;
auto mipIdx = getMipLevelOriginIdx ( image - > peekClMemObjType ( ) ) ;
UNRECOVERABLE_IF ( mipIdx > = 4 ) ;
writeOrigin [ mipIdx ] = unmapInfo . mipLevel ;
retVal = enqueueWriteImage ( image , CL_FALSE , writeOrigin , & unmapInfo . size [ 0 ] ,
2020-07-23 20:52:32 +08:00
image - > getHostPtrRowPitch ( ) , image - > getHostPtrSlicePitch ( ) , mappedPtr , memObj - > getMapAllocation ( getDevice ( ) . getRootDeviceIndex ( ) ) ,
2018-02-18 05:26:28 +08:00
eventsRequest . numEventsInWaitList , eventsRequest . eventWaitList , eventsRequest . outEvent ) ;
2018-02-01 20:40:30 +08:00
}
2018-02-18 05:26:28 +08:00
} else {
retVal = enqueueMarkerWithWaitList ( eventsRequest . numEventsInWaitList , eventsRequest . eventWaitList , eventsRequest . outEvent ) ;
2018-02-01 20:40:30 +08:00
}
2018-02-18 05:26:28 +08:00
if ( retVal = = CL_SUCCESS ) {
memObj - > removeMappedPtr ( mappedPtr ) ;
if ( eventsRequest . outEvent ) {
auto event = castToObject < Event > ( * eventsRequest . outEvent ) ;
event - > setCmdType ( CL_COMMAND_UNMAP_MEM_OBJECT ) ;
}
}
2018-02-21 22:25:46 +08:00
return retVal ;
2018-02-01 20:40:30 +08:00
}
2018-02-09 05:59:03 +08:00
void * CommandQueue : : enqueueReadMemObjForMap ( TransferProperties & transferProperties , EventsRequest & eventsRequest , cl_int & errcodeRet ) {
2019-11-07 21:15:04 +08:00
void * basePtr = transferProperties . memObj - > getBasePtrForMap ( getDevice ( ) . getRootDeviceIndex ( ) ) ;
2019-04-08 20:49:35 +08:00
size_t mapPtrOffset = transferProperties . memObj - > calculateOffsetForMapping ( transferProperties . offset ) + transferProperties . mipPtrOffset ;
if ( transferProperties . memObj - > peekClMemObjType ( ) = = CL_MEM_OBJECT_BUFFER ) {
mapPtrOffset + = transferProperties . memObj - > getOffset ( ) ;
}
void * returnPtr = ptrOffset ( basePtr , mapPtrOffset ) ;
2018-02-18 05:26:28 +08:00
if ( ! transferProperties . memObj - > addMappedPtr ( returnPtr , transferProperties . memObj - > calculateMappedPtrLength ( transferProperties . size ) ,
2021-10-18 23:07:01 +08:00
transferProperties . mapFlags , transferProperties . size , transferProperties . offset , transferProperties . mipLevel ,
transferProperties . memObj - > getMapAllocation ( getDevice ( ) . getRootDeviceIndex ( ) ) ) ) {
2018-02-18 05:26:28 +08:00
errcodeRet = CL_INVALID_OPERATION ;
return nullptr ;
}
2018-02-09 05:59:03 +08:00
2021-10-13 22:29:02 +08:00
if ( transferProperties . mapFlags = = CL_MAP_WRITE_INVALIDATE_REGION ) {
errcodeRet = enqueueMarkerWithWaitList ( eventsRequest . numEventsInWaitList , eventsRequest . eventWaitList , eventsRequest . outEvent ) ;
2018-02-09 05:59:03 +08:00
} else {
2021-10-13 22:29:02 +08:00
if ( transferProperties . memObj - > peekClMemObjType ( ) = = CL_MEM_OBJECT_BUFFER ) {
auto buffer = castToObject < Buffer > ( transferProperties . memObj ) ;
errcodeRet = enqueueReadBuffer ( buffer , transferProperties . blocking , transferProperties . offset [ 0 ] , transferProperties . size [ 0 ] ,
returnPtr , transferProperties . memObj - > getMapAllocation ( getDevice ( ) . getRootDeviceIndex ( ) ) , eventsRequest . numEventsInWaitList ,
eventsRequest . eventWaitList , eventsRequest . outEvent ) ;
} else {
auto image = castToObjectOrAbort < Image > ( transferProperties . memObj ) ;
size_t readOrigin [ 4 ] = { transferProperties . offset [ 0 ] , transferProperties . offset [ 1 ] , transferProperties . offset [ 2 ] , 0 } ;
auto mipIdx = getMipLevelOriginIdx ( image - > peekClMemObjType ( ) ) ;
UNRECOVERABLE_IF ( mipIdx > = 4 ) ;
readOrigin [ mipIdx ] = transferProperties . mipLevel ;
errcodeRet = enqueueReadImage ( image , transferProperties . blocking , readOrigin , & transferProperties . size [ 0 ] ,
image - > getHostPtrRowPitch ( ) , image - > getHostPtrSlicePitch ( ) ,
returnPtr , transferProperties . memObj - > getMapAllocation ( getDevice ( ) . getRootDeviceIndex ( ) ) , eventsRequest . numEventsInWaitList ,
eventsRequest . eventWaitList , eventsRequest . outEvent ) ;
}
2018-02-09 05:59:03 +08:00
}
2018-02-18 05:26:28 +08:00
if ( errcodeRet ! = CL_SUCCESS ) {
transferProperties . memObj - > removeMappedPtr ( returnPtr ) ;
return nullptr ;
}
if ( eventsRequest . outEvent ) {
auto event = castToObject < Event > ( * eventsRequest . outEvent ) ;
event - > setCmdType ( transferProperties . cmdType ) ;
2018-02-09 05:59:03 +08:00
}
return returnPtr ;
}
void * CommandQueue : : enqueueMapMemObject ( TransferProperties & transferProperties , EventsRequest & eventsRequest , cl_int & errcodeRet ) {
if ( transferProperties . memObj - > mappingOnCpuAllowed ( ) ) {
return cpuDataTransferHandler ( transferProperties , eventsRequest , errcodeRet ) ;
} else {
return enqueueReadMemObjForMap ( transferProperties , eventsRequest , errcodeRet ) ;
}
}
cl_int CommandQueue : : enqueueUnmapMemObject ( TransferProperties & transferProperties , EventsRequest & eventsRequest ) {
2018-07-19 20:28:21 +08:00
cl_int retVal = CL_SUCCESS ;
2018-02-09 05:59:03 +08:00
if ( transferProperties . memObj - > mappingOnCpuAllowed ( ) ) {
cpuDataTransferHandler ( transferProperties , eventsRequest , retVal ) ;
} else {
retVal = enqueueWriteMemObjForUnmap ( transferProperties . memObj , transferProperties . ptr , eventsRequest ) ;
}
return retVal ;
}
void * CommandQueue : : enqueueMapBuffer ( Buffer * buffer , cl_bool blockingMap ,
cl_map_flags mapFlags , size_t offset ,
size_t size , cl_uint numEventsInWaitList ,
const cl_event * eventWaitList , cl_event * event ,
cl_int & errcodeRet ) {
2020-05-26 00:27:17 +08:00
TransferProperties transferProperties ( buffer , CL_COMMAND_MAP_BUFFER , mapFlags , blockingMap ! = CL_FALSE , & offset , & size , nullptr , false , getDevice ( ) . getRootDeviceIndex ( ) ) ;
2018-02-09 05:59:03 +08:00
EventsRequest eventsRequest ( numEventsInWaitList , eventWaitList , event ) ;
return enqueueMapMemObject ( transferProperties , eventsRequest , errcodeRet ) ;
}
void * CommandQueue : : enqueueMapImage ( Image * image , cl_bool blockingMap ,
cl_map_flags mapFlags , const size_t * origin ,
const size_t * region , size_t * imageRowPitch ,
size_t * imageSlicePitch ,
cl_uint numEventsInWaitList ,
const cl_event * eventWaitList , cl_event * event ,
cl_int & errcodeRet ) {
2018-02-18 05:26:28 +08:00
TransferProperties transferProperties ( image , CL_COMMAND_MAP_IMAGE , mapFlags , blockingMap ! = CL_FALSE ,
2020-05-26 00:27:17 +08:00
const_cast < size_t * > ( origin ) , const_cast < size_t * > ( region ) , nullptr , false , getDevice ( ) . getRootDeviceIndex ( ) ) ;
2018-02-09 05:59:03 +08:00
EventsRequest eventsRequest ( numEventsInWaitList , eventWaitList , event ) ;
2018-02-18 20:07:53 +08:00
if ( image - > isMemObjZeroCopy ( ) & & image - > mappingOnCpuAllowed ( ) ) {
GetInfoHelper : : set ( imageSlicePitch , image - > getImageDesc ( ) . image_slice_pitch ) ;
2018-04-11 23:40:42 +08:00
if ( image - > getImageDesc ( ) . image_type = = CL_MEM_OBJECT_IMAGE1D_ARRAY ) {
// There are differences in qPitch programming between Gen8 vs Gen9+ devices.
// For Gen8 qPitch is distance in rows while Gen9+ it is in pixels.
// Minimum value of qPitch is 4 and this causes slicePitch = 4*rowPitch on Gen8.
// To allow zero-copy we have to tell what is correct value rowPitch which should equal to slicePitch.
GetInfoHelper : : set ( imageRowPitch , image - > getImageDesc ( ) . image_slice_pitch ) ;
} else {
GetInfoHelper : : set ( imageRowPitch , image - > getImageDesc ( ) . image_row_pitch ) ;
}
2018-02-18 20:07:53 +08:00
} else {
2018-09-04 21:25:29 +08:00
GetInfoHelper : : set ( imageSlicePitch , image - > getHostPtrSlicePitch ( ) ) ;
GetInfoHelper : : set ( imageRowPitch , image - > getHostPtrRowPitch ( ) ) ;
2018-02-18 20:07:53 +08:00
}
2018-04-04 15:29:48 +08:00
if ( Image : : hasSlices ( image - > peekClMemObjType ( ) ) = = false ) {
GetInfoHelper : : set ( imageSlicePitch , static_cast < size_t > ( 0 ) ) ;
}
2018-09-04 21:25:29 +08:00
return enqueueMapMemObject ( transferProperties , eventsRequest , errcodeRet ) ;
2018-02-09 05:59:03 +08:00
}
cl_int CommandQueue : : enqueueUnmapMemObject ( MemObj * memObj , void * mappedPtr , cl_uint numEventsInWaitList , const cl_event * eventWaitList , cl_event * event ) {
2020-05-26 00:27:17 +08:00
TransferProperties transferProperties ( memObj , CL_COMMAND_UNMAP_MEM_OBJECT , 0 , false , nullptr , nullptr , mappedPtr , false , getDevice ( ) . getRootDeviceIndex ( ) ) ;
2018-02-09 05:59:03 +08:00
EventsRequest eventsRequest ( numEventsInWaitList , eventWaitList , event ) ;
return enqueueUnmapMemObject ( transferProperties , eventsRequest ) ;
}
void CommandQueue : : enqueueBlockedMapUnmapOperation ( const cl_event * eventWaitList ,
size_t numEventsInWaitlist ,
MapOperationType opType ,
MemObj * memObj ,
2018-02-18 05:26:28 +08:00
MemObjSizeArray & copySize ,
MemObjOffsetArray & copyOffset ,
bool readOnly ,
2018-02-09 05:59:03 +08:00
EventBuilder & externalEventBuilder ) {
EventBuilder internalEventBuilder ;
EventBuilder * eventBuilder ;
// check if event will be exposed externally
if ( externalEventBuilder . getEvent ( ) ) {
externalEventBuilder . getEvent ( ) - > incRefInternal ( ) ;
eventBuilder = & externalEventBuilder ;
} else {
// it will be an internal event
internalEventBuilder . create < VirtualEvent > ( this , context ) ;
eventBuilder = & internalEventBuilder ;
}
//store task data in event
2019-07-23 03:28:59 +08:00
auto cmd = std : : unique_ptr < Command > ( new CommandMapUnmap ( opType , * memObj , copySize , copyOffset , readOnly , * this ) ) ;
2018-02-09 05:59:03 +08:00
eventBuilder - > getEvent ( ) - > setCommand ( std : : move ( cmd ) ) ;
//bind output event with input events
eventBuilder - > addParentEvents ( ArrayRef < const cl_event > ( eventWaitList , numEventsInWaitlist ) ) ;
eventBuilder - > addParentEvent ( this - > virtualEvent ) ;
eventBuilder - > finalize ( ) ;
if ( this - > virtualEvent ) {
this - > virtualEvent - > decRefInternal ( ) ;
}
this - > virtualEvent = eventBuilder - > getEvent ( ) ;
}
2018-03-21 19:58:30 +08:00
bool CommandQueue : : setupDebugSurface ( Kernel * kernel ) {
2019-07-15 20:28:09 +08:00
auto debugSurface = getGpgpuCommandStreamReceiver ( ) . getDebugSurfaceAllocation ( ) ;
2021-03-22 23:26:03 +08:00
auto surfaceState = ptrOffset ( reinterpret_cast < uintptr_t * > ( kernel - > getSurfaceStateHeap ( ) ) ,
kernel - > getKernelInfo ( ) . kernelDescriptor . payloadMappings . implicitArgs . systemThreadSurfaceAddress . bindful ) ;
2018-03-21 19:58:30 +08:00
void * addressToPatch = reinterpret_cast < void * > ( debugSurface - > getGpuAddress ( ) ) ;
size_t sizeToPatch = debugSurface - > getUnderlyingBufferSize ( ) ;
2021-03-03 20:25:26 +08:00
Buffer : : setSurfaceState ( & device - > getDevice ( ) , surfaceState , false , false , sizeToPatch ,
addressToPatch , 0 , debugSurface , 0 , 0 ,
2021-03-22 23:26:03 +08:00
kernel - > getKernelInfo ( ) . kernelDescriptor . kernelAttributes . flags . useGlobalAtomics ,
2021-03-30 01:06:29 +08:00
kernel - > areMultipleSubDevicesInContext ( ) ) ;
2018-03-21 19:58:30 +08:00
return true ;
}
2020-11-24 21:29:07 +08:00
bool CommandQueue : : validateCapability ( cl_command_queue_capabilities_intel capability ) const {
2020-12-08 20:40:04 +08:00
return this - > queueCapabilities = = CL_QUEUE_DEFAULT_CAPABILITIES_INTEL | | isValueSet ( this - > queueCapabilities , capability ) ;
2020-11-24 21:29:07 +08:00
}
2020-12-15 02:07:09 +08:00
bool CommandQueue : : validateCapabilitiesForEventWaitList ( cl_uint numEventsInWaitList , const cl_event * waitList ) const {
for ( cl_uint eventIndex = 0u ; eventIndex < numEventsInWaitList ; eventIndex + + ) {
const Event * event = castToObject < Event > ( waitList [ eventIndex ] ) ;
if ( event - > isUserEvent ( ) ) {
continue ;
}
const CommandQueue * eventCommandQueue = event - > getCommandQueue ( ) ;
const bool crossQueue = this ! = eventCommandQueue ;
const cl_command_queue_capabilities_intel createCap = crossQueue ? CL_QUEUE_CAPABILITY_CREATE_CROSS_QUEUE_EVENTS_INTEL
: CL_QUEUE_CAPABILITY_CREATE_SINGLE_QUEUE_EVENTS_INTEL ;
const cl_command_queue_capabilities_intel waitCap = crossQueue ? CL_QUEUE_CAPABILITY_CROSS_QUEUE_EVENT_WAIT_LIST_INTEL
: CL_QUEUE_CAPABILITY_SINGLE_QUEUE_EVENT_WAIT_LIST_INTEL ;
if ( ! validateCapability ( waitCap ) | | ! eventCommandQueue - > validateCapability ( createCap ) ) {
return false ;
}
}
return true ;
}
bool CommandQueue : : validateCapabilityForOperation ( cl_command_queue_capabilities_intel capability ,
cl_uint numEventsInWaitList ,
const cl_event * waitList ,
const cl_event * outEvent ) const {
2020-11-24 21:29:07 +08:00
const bool operationValid = validateCapability ( capability ) ;
2020-12-15 02:07:09 +08:00
const bool waitListValid = validateCapabilitiesForEventWaitList ( numEventsInWaitList , waitList ) ;
2020-12-08 20:40:04 +08:00
const bool outEventValid = outEvent = = nullptr | |
2020-12-15 02:07:09 +08:00
validateCapability ( CL_QUEUE_CAPABILITY_CREATE_SINGLE_QUEUE_EVENTS_INTEL ) | |
validateCapability ( CL_QUEUE_CAPABILITY_CREATE_CROSS_QUEUE_EVENTS_INTEL ) ;
2020-11-24 21:29:07 +08:00
return operationValid & & waitListValid & & outEventValid ;
}
2021-02-11 21:26:05 +08:00
cl_uint CommandQueue : : getQueueFamilyIndex ( ) const {
if ( isQueueFamilySelected ( ) ) {
return queueFamilyIndex ;
} else {
const auto & hwInfo = device - > getHardwareInfo ( ) ;
const auto & hwHelper = HwHelper : : get ( hwInfo . platform . eRenderCoreFamily ) ;
2021-08-17 02:24:13 +08:00
const auto engineGroupType = hwHelper . getEngineGroupType ( gpgpuEngine - > getEngineType ( ) , gpgpuEngine - > getEngineUsage ( ) , hwInfo ) ;
2021-12-03 22:30:46 +08:00
const auto familyIndex = device - > getDevice ( ) . getEngineGroupIndexFromEngineGroupType ( engineGroupType ) ;
2021-02-11 21:26:05 +08:00
return static_cast < cl_uint > ( familyIndex ) ;
}
}
2021-09-18 01:09:06 +08:00
void CommandQueue : : updateBcsTaskCount ( aub_stream : : EngineType bcsEngineType , uint32_t newBcsTaskCount ) {
2021-10-06 23:19:50 +08:00
CopyEngineState & state = bcsStates [ EngineHelpers : : getBcsIndex ( bcsEngineType ) ] ;
state . engineType = bcsEngineType ;
state . taskCount = newBcsTaskCount ;
2021-09-18 01:09:06 +08:00
}
2021-08-27 00:38:39 +08:00
uint32_t CommandQueue : : peekBcsTaskCount ( aub_stream : : EngineType bcsEngineType ) const {
2021-10-06 23:19:50 +08:00
const CopyEngineState & state = bcsStates [ EngineHelpers : : getBcsIndex ( bcsEngineType ) ] ;
return state . taskCount ;
2021-08-27 00:38:39 +08:00
}
2021-12-06 18:01:46 +08:00
bool CommandQueue : : isTextureCacheFlushNeeded ( uint32_t commandType ) const {
return commandType = = CL_COMMAND_COPY_IMAGE & & getGpgpuCommandStreamReceiver ( ) . isDirectSubmissionEnabled ( ) ;
}
2018-04-26 16:01:01 +08:00
IndirectHeap & CommandQueue : : getIndirectHeap ( IndirectHeap : : Type heapType , size_t minRequiredSize ) {
2019-07-15 20:28:09 +08:00
return getGpgpuCommandStreamReceiver ( ) . getIndirectHeap ( heapType , minRequiredSize ) ;
2018-04-26 16:01:01 +08:00
}
2018-04-05 21:12:28 +08:00
2018-04-26 16:01:01 +08:00
void CommandQueue : : allocateHeapMemory ( IndirectHeap : : Type heapType , size_t minRequiredSize , IndirectHeap * & indirectHeap ) {
2019-07-15 20:28:09 +08:00
getGpgpuCommandStreamReceiver ( ) . allocateHeapMemory ( heapType , minRequiredSize , indirectHeap ) ;
2018-04-26 16:01:01 +08:00
}
2018-04-05 21:12:28 +08:00
2018-04-26 16:01:01 +08:00
void CommandQueue : : releaseIndirectHeap ( IndirectHeap : : Type heapType ) {
2019-07-15 20:28:09 +08:00
getGpgpuCommandStreamReceiver ( ) . releaseIndirectHeap ( heapType ) ;
2018-04-05 21:12:28 +08:00
}
2018-04-26 16:01:01 +08:00
2021-08-26 00:03:15 +08:00
void CommandQueue : : obtainNewTimestampPacketNodes ( size_t numberOfNodes , TimestampPacketContainer & previousNodes , bool clearAllDependencies , CommandStreamReceiver & csr ) {
TagAllocatorBase * allocator = csr . getTimestampPacketAllocator ( ) ;
2018-08-28 20:11:25 +08:00
2018-10-03 05:37:30 +08:00
previousNodes . swapNodes ( * timestampPacketContainer ) ;
2020-07-07 20:40:29 +08:00
2021-06-23 19:04:10 +08:00
if ( clearAllDependencies ) {
previousNodes . moveNodesToNewContainer ( * deferredTimestampPackets ) ;
}
2018-10-03 05:37:30 +08:00
DEBUG_BREAK_IF ( timestampPacketContainer - > peekNodes ( ) . size ( ) > 0 ) ;
for ( size_t i = 0 ; i < numberOfNodes ; i + + ) {
timestampPacketContainer - > add ( allocator - > getTag ( ) ) ;
2018-09-10 20:24:11 +08:00
}
2018-08-28 20:11:25 +08:00
}
2019-02-21 23:59:10 +08:00
size_t CommandQueue : : estimateTimestampPacketNodesCount ( const MultiDispatchInfo & dispatchInfo ) const {
size_t nodesCount = dispatchInfo . size ( ) ;
auto mainKernel = dispatchInfo . peekMainKernel ( ) ;
2020-03-06 21:56:23 +08:00
if ( obtainTimestampPacketForCacheFlush ( mainKernel - > requiresCacheFlushCommand ( * this ) ) ) {
2019-02-21 23:59:10 +08:00
nodesCount + + ;
}
return nodesCount ;
}
2019-05-30 20:36:12 +08:00
bool CommandQueue : : bufferCpuCopyAllowed ( Buffer * buffer , cl_command_type commandType , cl_bool blocking , size_t size , void * ptr ,
cl_uint numEventsInWaitList , const cl_event * eventWaitList ) {
2020-02-25 20:39:23 +08:00
auto debugVariableSet = false ;
2019-05-30 20:36:12 +08:00
// Requested by debug variable or allowed by Buffer
2020-02-25 20:39:23 +08:00
if ( CL_COMMAND_READ_BUFFER = = commandType & & DebugManager . flags . DoCpuCopyOnReadBuffer . get ( ) ! = - 1 ) {
if ( DebugManager . flags . DoCpuCopyOnReadBuffer . get ( ) = = 0 ) {
return false ;
}
debugVariableSet = true ;
}
if ( CL_COMMAND_WRITE_BUFFER = = commandType & & DebugManager . flags . DoCpuCopyOnWriteBuffer . get ( ) ! = - 1 ) {
if ( DebugManager . flags . DoCpuCopyOnWriteBuffer . get ( ) = = 0 ) {
return false ;
}
debugVariableSet = true ;
}
2019-05-30 20:36:12 +08:00
2020-02-21 15:25:43 +08:00
//if we are blocked by user events, we can't service the call on CPU
if ( Event : : checkUserEventDependencies ( numEventsInWaitList , eventWaitList ) ) {
return false ;
}
2020-02-21 18:11:36 +08:00
//check if buffer is compatible
2021-03-02 03:07:28 +08:00
if ( ! buffer - > isReadWriteOnCpuAllowed ( device - > getDevice ( ) ) ) {
2020-02-21 16:48:51 +08:00
return false ;
}
2020-03-12 14:23:27 +08:00
if ( buffer - > getMemoryManager ( ) & & buffer - > getMemoryManager ( ) - > isCpuCopyRequired ( ptr ) ) {
return true ;
}
2020-02-21 16:48:51 +08:00
if ( debugVariableSet ) {
2020-02-21 15:25:43 +08:00
return true ;
}
2020-02-21 16:48:51 +08:00
//non blocking transfers are not expected to be serviced by CPU
//we do not want to artifically stall the pipeline to allow CPU access
if ( blocking = = CL_FALSE ) {
return false ;
}
2020-02-21 18:11:36 +08:00
//check if it is beneficial to do transfer on CPU
2020-06-25 16:49:29 +08:00
if ( ! buffer - > isReadWriteOnCpuPreferred ( ptr , size , getDevice ( ) ) ) {
2020-02-21 15:25:43 +08:00
return false ;
}
//make sure that event wait list is empty
if ( numEventsInWaitList = = 0 ) {
return true ;
}
return false ;
2019-05-30 20:36:12 +08:00
}
2019-06-05 15:35:58 +08:00
2019-06-13 15:56:06 +08:00
bool CommandQueue : : queueDependenciesClearRequired ( ) const {
return isOOQEnabled ( ) | | DebugManager . flags . OmitTimestampPacketDependencies . get ( ) ;
}
2019-06-18 17:02:47 +08:00
2021-09-07 01:04:14 +08:00
bool CommandQueue : : blitEnqueueAllowed ( const CsrSelectionArgs & args ) const {
2021-09-02 18:14:12 +08:00
bool blitEnqueueAllowed = getGpgpuCommandStreamReceiver ( ) . peekTimestampPacketWriteEnabled ( ) | | this - > isCopyOnly ;
2020-10-27 21:06:44 +08:00
if ( DebugManager . flags . EnableBlitterForEnqueueOperations . get ( ) ! = - 1 ) {
2021-09-02 18:14:12 +08:00
blitEnqueueAllowed = DebugManager . flags . EnableBlitterForEnqueueOperations . get ( ) ;
2020-10-20 21:27:49 +08:00
}
2021-09-07 01:04:14 +08:00
if ( ! blitEnqueueAllowed ) {
return false ;
}
2020-10-20 21:27:49 +08:00
2021-09-07 01:04:14 +08:00
switch ( args . cmdType ) {
2020-10-20 21:27:49 +08:00
case CL_COMMAND_READ_BUFFER :
case CL_COMMAND_WRITE_BUFFER :
case CL_COMMAND_COPY_BUFFER :
case CL_COMMAND_READ_BUFFER_RECT :
case CL_COMMAND_WRITE_BUFFER_RECT :
case CL_COMMAND_COPY_BUFFER_RECT :
case CL_COMMAND_SVM_MEMCPY :
2021-09-07 01:04:14 +08:00
case CL_COMMAND_SVM_MAP :
case CL_COMMAND_SVM_UNMAP :
return true ;
2020-10-20 21:27:49 +08:00
case CL_COMMAND_READ_IMAGE :
2021-09-07 01:04:14 +08:00
return blitEnqueueImageAllowed ( args . srcResource . imageOrigin , args . size , * args . srcResource . image ) ;
2020-10-20 21:27:49 +08:00
case CL_COMMAND_WRITE_IMAGE :
2021-09-07 01:04:14 +08:00
return blitEnqueueImageAllowed ( args . dstResource . imageOrigin , args . size , * args . dstResource . image ) ;
2021-07-26 08:49:41 +08:00
case CL_COMMAND_COPY_IMAGE :
2021-09-07 01:04:14 +08:00
return blitEnqueueImageAllowed ( args . srcResource . imageOrigin , args . size , * args . srcResource . image ) & &
blitEnqueueImageAllowed ( args . dstResource . imageOrigin , args . size , * args . dstResource . image ) ;
2020-10-20 21:27:49 +08:00
default :
return false ;
}
2019-06-18 17:02:47 +08:00
}
2019-07-23 02:55:09 +08:00
2021-09-07 01:04:14 +08:00
bool CommandQueue : : blitEnqueueImageAllowed ( const size_t * origin , const size_t * region , const Image & image ) const {
2021-04-22 21:11:33 +08:00
const auto & hwInfo = device - > getHardwareInfo ( ) ;
2021-10-13 21:30:45 +08:00
const auto & hwInfoConfig = HwInfoConfig : : get ( hwInfo . platform . eProductFamily ) ;
auto blitEnqueueImageAllowed = hwInfoConfig - > isBlitterForImagesSupported ( ) ;
2020-10-28 00:17:26 +08:00
2021-07-30 08:33:41 +08:00
if ( DebugManager . flags . EnableBlitterForEnqueueImageOperations . get ( ) ! = - 1 ) {
blitEnqueueImageAllowed = DebugManager . flags . EnableBlitterForEnqueueImageOperations . get ( ) ;
2020-11-06 19:38:49 +08:00
}
2021-07-26 08:08:39 +08:00
blitEnqueueImageAllowed & = ! isMipMapped ( image . getImageDesc ( ) ) ;
2021-06-10 20:53:07 +08:00
2021-10-15 23:24:03 +08:00
const auto & defaultGmm = image . getGraphicsAllocation ( device - > getRootDeviceIndex ( ) ) - > getDefaultGmm ( ) ;
if ( defaultGmm ! = nullptr ) {
auto isTile64 = defaultGmm - > gmmResourceInfo - > getResourceFlags ( ) - > Info . Tile64 ;
auto imageType = image . getImageDesc ( ) . image_type ;
if ( isTile64 & & ( imageType = = CL_MEM_OBJECT_IMAGE3D ) ) {
blitEnqueueImageAllowed & = hwInfoConfig - > isTile64With3DSurfaceOnBCSSupported ( hwInfo ) ;
}
}
2021-07-26 08:08:39 +08:00
return blitEnqueueImageAllowed ;
2020-10-28 00:17:26 +08:00
}
2021-06-22 21:16:27 +08:00
bool CommandQueue : : isBlockedCommandStreamRequired ( uint32_t commandType , const EventsRequest & eventsRequest , bool blockedQueue , bool isMarkerWithProfiling ) const {
2019-07-23 02:55:09 +08:00
if ( ! blockedQueue ) {
return false ;
}
2021-06-22 21:16:27 +08:00
if ( isCacheFlushCommand ( commandType ) | | ! isCommandWithoutKernel ( commandType ) | | isMarkerWithProfiling ) {
2019-07-23 02:55:09 +08:00
return true ;
}
2021-06-14 23:33:53 +08:00
if ( CL_COMMAND_BARRIER = = commandType | | CL_COMMAND_MARKER = = commandType ) {
auto timestampPacketWriteEnabled = getGpgpuCommandStreamReceiver ( ) . peekTimestampPacketWriteEnabled ( ) ;
if ( timestampPacketWriteEnabled | | context - > getRootDeviceIndices ( ) . size ( ) > 1 ) {
2019-07-23 02:55:09 +08:00
2021-06-14 23:33:53 +08:00
for ( size_t i = 0 ; i < eventsRequest . numEventsInWaitList ; i + + ) {
auto waitlistEvent = castToObjectOrAbort < Event > ( eventsRequest . eventWaitList [ i ] ) ;
if ( timestampPacketWriteEnabled & & waitlistEvent - > getTimestampPacketNodes ( ) ) {
return true ;
}
if ( waitlistEvent - > getCommandQueue ( ) & & waitlistEvent - > getCommandQueue ( ) - > getDevice ( ) . getRootDeviceIndex ( ) ! = this - > getDevice ( ) . getRootDeviceIndex ( ) ) {
return true ;
}
2019-07-23 02:55:09 +08:00
}
}
}
return false ;
}
2019-08-02 21:56:28 +08:00
2020-05-27 23:12:32 +08:00
void CommandQueue : : storeProperties ( const cl_queue_properties * properties ) {
if ( properties ) {
for ( size_t i = 0 ; properties [ i ] ! = 0 ; i + = 2 ) {
propertiesVector . push_back ( properties [ i ] ) ;
propertiesVector . push_back ( properties [ i + 1 ] ) ;
}
propertiesVector . push_back ( 0 ) ;
}
}
2020-11-13 22:28:52 +08:00
void CommandQueue : : processProperties ( const cl_queue_properties * properties ) {
2020-11-16 19:43:03 +08:00
if ( properties ! = nullptr ) {
bool specificEngineSelected = false ;
cl_uint selectedQueueFamilyIndex = std : : numeric_limits < uint32_t > : : max ( ) ;
cl_uint selectedQueueIndex = std : : numeric_limits < uint32_t > : : max ( ) ;
for ( auto currentProperties = properties ; * currentProperties ! = 0 ; currentProperties + = 2 ) {
switch ( * currentProperties ) {
case CL_QUEUE_FAMILY_INTEL :
selectedQueueFamilyIndex = static_cast < cl_uint > ( * ( currentProperties + 1 ) ) ;
specificEngineSelected = true ;
break ;
case CL_QUEUE_INDEX_INTEL :
selectedQueueIndex = static_cast < cl_uint > ( * ( currentProperties + 1 ) ) ;
specificEngineSelected = true ;
break ;
}
}
if ( specificEngineSelected ) {
2020-11-26 02:10:05 +08:00
this - > queueFamilySelected = true ;
2021-09-01 00:49:46 +08:00
if ( ! getDevice ( ) . hasRootCsr ( ) ) {
2021-12-13 20:45:24 +08:00
const auto & engine = getDevice ( ) . getRegularEngineGroups ( ) [ selectedQueueFamilyIndex ] . engines [ selectedQueueIndex ] ;
2020-11-16 19:43:03 +08:00
auto engineType = engine . getEngineType ( ) ;
2021-08-17 02:24:13 +08:00
auto engineUsage = engine . getEngineUsage ( ) ;
2021-12-02 01:59:35 +08:00
if ( ( DebugManager . flags . EngineUsageHint . get ( ) ! = - 1 ) & &
( getDevice ( ) . tryGetEngine ( engineType , static_cast < EngineUsage > ( DebugManager . flags . EngineUsageHint . get ( ) ) ) ! = nullptr ) ) {
engineUsage = static_cast < EngineUsage > ( DebugManager . flags . EngineUsageHint . get ( ) ) ;
}
2021-08-17 02:24:13 +08:00
this - > overrideEngine ( engineType , engineUsage ) ;
2020-11-24 21:29:07 +08:00
this - > queueCapabilities = getClDevice ( ) . getDeviceInfo ( ) . queueFamilyProperties [ selectedQueueFamilyIndex ] . capabilities ;
2020-11-26 02:10:05 +08:00
this - > queueFamilyIndex = selectedQueueFamilyIndex ;
this - > queueIndexWithinFamily = selectedQueueIndex ;
2020-11-16 19:43:03 +08:00
}
}
}
2021-07-02 05:07:56 +08:00
requiresCacheFlushAfterWalker = device & & ( device - > getDeviceInfo ( ) . parentDevice ! = nullptr ) ;
2020-11-13 22:28:52 +08:00
}
2021-08-17 02:24:13 +08:00
void CommandQueue : : overrideEngine ( aub_stream : : EngineType engineType , EngineUsage engineUsage ) {
2021-01-20 01:32:22 +08:00
const HardwareInfo & hwInfo = getDevice ( ) . getHardwareInfo ( ) ;
const HwHelper & hwHelper = HwHelper : : get ( hwInfo . platform . eRenderCoreFamily ) ;
2021-08-17 02:24:13 +08:00
const EngineGroupType engineGroupType = hwHelper . getEngineGroupType ( engineType , engineUsage , hwInfo ) ;
2021-01-20 01:32:22 +08:00
const bool isEngineCopyOnly = hwHelper . isCopyOnlyEngineType ( engineGroupType ) ;
if ( isEngineCopyOnly ) {
2021-09-25 00:32:20 +08:00
std : : fill ( bcsEngines . begin ( ) , bcsEngines . end ( ) , nullptr ) ;
bcsEngines [ EngineHelpers : : getBcsIndex ( engineType ) ] = & device - > getEngine ( engineType , EngineUsage : : Regular ) ;
2021-11-04 22:48:13 +08:00
bcsEngineTypes = { engineType } ;
2020-11-16 19:43:03 +08:00
timestampPacketContainer = std : : make_unique < TimestampPacketContainer > ( ) ;
2021-06-15 00:57:09 +08:00
deferredTimestampPackets = std : : make_unique < TimestampPacketContainer > ( ) ;
2020-11-16 19:43:03 +08:00
isCopyOnly = true ;
} else {
2021-12-02 01:59:35 +08:00
gpgpuEngine = & device - > getEngine ( engineType , engineUsage ) ;
2020-11-16 19:43:03 +08:00
}
}
2019-08-02 21:56:28 +08:00
void CommandQueue : : aubCaptureHook ( bool & blocking , bool & clearAllDependencies , const MultiDispatchInfo & multiDispatchInfo ) {
if ( DebugManager . flags . AUBDumpSubCaptureMode . get ( ) ) {
2021-10-04 20:18:04 +08:00
auto status = getGpgpuCommandStreamReceiver ( ) . checkAndActivateAubSubCapture ( multiDispatchInfo . empty ( ) ? " " : multiDispatchInfo . peekMainKernel ( ) - > getDescriptor ( ) . kernelMetadata . kernelName ) ;
2019-08-02 21:56:28 +08:00
if ( ! status . isActive ) {
// make each enqueue blocking when subcapture is not active to split batch buffer
blocking = true ;
} else if ( ! status . wasActiveInPreviousEnqueue ) {
// omit timestamp packet dependencies dependencies upon subcapture activation
clearAllDependencies = true ;
}
}
if ( getGpgpuCommandStreamReceiver ( ) . getType ( ) > CommandStreamReceiverType : : CSR_HW ) {
for ( auto & dispatchInfo : multiDispatchInfo ) {
2021-07-20 00:12:54 +08:00
auto & kernelName = dispatchInfo . getKernel ( ) - > getKernelInfo ( ) . kernelDescriptor . kernelMetadata . kernelName ;
2019-08-02 21:56:28 +08:00
getGpgpuCommandStreamReceiver ( ) . addAubComment ( kernelName . c_str ( ) ) ;
}
}
}
2020-06-24 19:32:09 +08:00
2022-03-04 16:39:42 +08:00
bool CommandQueue : : isWaitForTimestampsEnabled ( ) const {
2021-12-09 19:59:52 +08:00
auto & hwHelper = HwHelper : : get ( getDevice ( ) . getHardwareInfo ( ) . platform . eRenderCoreFamily ) ;
auto enabled = CommandQueue : : isTimestampWaitEnabled ( ) ;
enabled & = hwHelper . isTimestampWaitSupported ( ) ;
2021-11-17 23:05:48 +08:00
switch ( DebugManager . flags . EnableTimestampWait . get ( ) ) {
case 0 :
enabled = false ;
break ;
case 1 :
enabled = getGpgpuCommandStreamReceiver ( ) . isUpdateTagFromWaitEnabled ( ) ;
break ;
case 2 :
enabled = getGpgpuCommandStreamReceiver ( ) . isDirectSubmissionEnabled ( ) ;
break ;
case 3 :
enabled = getGpgpuCommandStreamReceiver ( ) . isAnyDirectSubmissionEnabled ( ) ;
break ;
case 4 :
enabled = true ;
break ;
}
return enabled ;
}
2022-02-28 18:24:05 +08:00
WaitStatus CommandQueue : : waitForAllEngines ( bool blockedQueue , PrintfHandler * printfHandler , bool cleanTemporaryAllocationsList ) {
2020-08-26 21:44:12 +08:00
if ( blockedQueue ) {
while ( isQueueBlocked ( ) ) {
}
}
2021-12-09 19:59:52 +08:00
auto waitedOnTimestamps = waitForTimestamps ( taskCount ) ;
2021-09-22 23:07:20 +08:00
TimestampPacketContainer nodesToRelease ;
if ( deferredTimestampPackets ) {
deferredTimestampPackets - > swapNodes ( nodesToRelease ) ;
}
2021-10-06 23:19:50 +08:00
StackVec < CopyEngineState , bcsInfoMaskSize > activeBcsStates { } ;
for ( CopyEngineState & state : this - > bcsStates ) {
if ( state . isValid ( ) ) {
activeBcsStates . push_back ( state ) ;
}
}
2022-02-28 18:24:05 +08:00
const auto waitStatus = waitUntilComplete ( taskCount , activeBcsStates , flushStamp - > peekStamp ( ) , false , cleanTemporaryAllocationsList , waitedOnTimestamps ) ;
2020-08-26 21:44:12 +08:00
if ( printfHandler ) {
printfHandler - > printEnqueueOutput ( ) ;
}
2022-02-28 18:24:05 +08:00
return waitStatus ;
2020-08-26 21:44:12 +08:00
}
2021-12-29 22:28:21 +08:00
void CommandQueue : : setupBarrierTimestampForBcsEngines ( aub_stream : : EngineType engineType , TimestampPacketDependencies & timestampPacketDependencies ) {
if ( ! getGpgpuCommandStreamReceiver ( ) . isStallingCommandsOnNextFlushRequired ( ) ) {
return ;
}
// Ensure we have exactly 1 barrier node.
if ( timestampPacketDependencies . barrierNodes . peekNodes ( ) . empty ( ) ) {
timestampPacketDependencies . barrierNodes . add ( getGpgpuCommandStreamReceiver ( ) . getTimestampPacketAllocator ( ) - > getTag ( ) ) ;
}
if ( isOOQEnabled ( ) ) {
// Barrier node will be signalled on gpgpuCsr. Save it for later use on blitters.
for ( auto currentBcsIndex = 0u ; currentBcsIndex < bcsTimestampPacketContainers . size ( ) ; currentBcsIndex + + ) {
const auto currentBcsEngineType = EngineHelpers : : mapBcsIndexToEngineType ( currentBcsIndex , true ) ;
if ( currentBcsEngineType = = engineType ) {
// Node is already added to barrierNodes for this engine, no need to save it.
continue ;
}
// Save latest timestamp (override previous, if any).
2022-03-22 18:53:44 +08:00
if ( ! bcsTimestampPacketContainers [ currentBcsIndex ] . lastBarrierToWaitFor . peekNodes ( ) . empty ( ) ) {
std : : array < uint32_t , 8u > timestampData ;
timestampData . fill ( std : : numeric_limits < uint32_t > : : max ( ) ) ;
for ( auto & node : bcsTimestampPacketContainers [ currentBcsIndex ] . lastBarrierToWaitFor . peekNodes ( ) ) {
for ( uint32_t i = 0 ; i < node - > getPacketsUsed ( ) ; i + + ) {
node - > assignDataToAllTimestamps ( i , timestampData . data ( ) ) ;
}
}
}
2021-12-29 22:28:21 +08:00
TimestampPacketContainer newContainer { } ;
newContainer . assignAndIncrementNodesRefCounts ( timestampPacketDependencies . barrierNodes ) ;
bcsTimestampPacketContainers [ currentBcsIndex ] . lastBarrierToWaitFor . swapNodes ( newContainer ) ;
}
}
}
void CommandQueue : : processBarrierTimestampForBcsEngine ( aub_stream : : EngineType bcsEngineType , TimestampPacketDependencies & blitDependencies ) {
BcsTimestampPacketContainers & bcsContainers = bcsTimestampPacketContainers [ EngineHelpers : : getBcsIndex ( bcsEngineType ) ] ;
bcsContainers . lastBarrierToWaitFor . moveNodesToNewContainer ( blitDependencies . barrierNodes ) ;
}
void CommandQueue : : setLastBcsPacket ( aub_stream : : EngineType bcsEngineType ) {
if ( isOOQEnabled ( ) ) {
TimestampPacketContainer dummyContainer { } ;
dummyContainer . assignAndIncrementNodesRefCounts ( * this - > timestampPacketContainer ) ;
BcsTimestampPacketContainers & bcsContainers = bcsTimestampPacketContainers [ EngineHelpers : : getBcsIndex ( bcsEngineType ) ] ;
bcsContainers . lastSignalledPacket . swapNodes ( dummyContainer ) ;
}
}
void CommandQueue : : fillCsrDependenciesWithLastBcsPackets ( CsrDependencies & csrDeps ) {
for ( BcsTimestampPacketContainers & bcsContainers : bcsTimestampPacketContainers ) {
if ( bcsContainers . lastSignalledPacket . peekNodes ( ) . empty ( ) ) {
continue ;
}
csrDeps . timestampPacketContainer . push_back ( & bcsContainers . lastSignalledPacket ) ;
}
}
void CommandQueue : : clearLastBcsPackets ( ) {
for ( BcsTimestampPacketContainers & bcsContainers : bcsTimestampPacketContainers ) {
bcsContainers . lastSignalledPacket . moveNodesToNewContainer ( * deferredTimestampPackets ) ;
}
}
2019-03-26 18:59:46 +08:00
} // namespace NEO