2017-12-21 07:45:38 +08:00
/*
2018-09-19 04:40:46 +08:00
* Copyright ( C ) 2018 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
*
*/
2018-08-12 00:12:28 +08:00
# include "runtime/built_ins/builtins_dispatch_builder.h"
2017-12-21 07:45:38 +08:00
# include "runtime/command_queue/command_queue.h"
# include "runtime/command_stream/command_stream_receiver.h"
# include "runtime/context/context.h"
# include "runtime/device/device.h"
# include "runtime/device_queue/device_queue.h"
2018-10-29 17:38:53 +08:00
# include "runtime/event/user_event.h"
2018-02-09 05:59:03 +08:00
# include "runtime/event/event_builder.h"
2018-02-08 23:00:20 +08:00
# include "runtime/gtpin/gtpin_notify.h"
2017-12-21 07:45:38 +08:00
# include "runtime/helpers/aligned_memory.h"
# include "runtime/helpers/array_count.h"
# include "runtime/helpers/get_info.h"
2018-04-04 15:29:48 +08:00
# include "runtime/helpers/mipmap.h"
2017-12-21 07:45:38 +08:00
# include "runtime/helpers/options.h"
2018-09-26 06:44:43 +08:00
# include "runtime/helpers/kernel_commands.h"
2017-12-21 07:45:38 +08:00
# include "runtime/helpers/ptr_math.h"
2018-08-28 20:11:25 +08:00
# include "runtime/helpers/timestamp_packet.h"
2017-12-21 07:45:38 +08:00
# include "runtime/mem_obj/buffer.h"
# include "runtime/mem_obj/image.h"
# include "runtime/helpers/surface_formats.h"
2018-10-24 20:25:04 +08:00
# include "runtime/memory_manager/internal_allocation_storage.h"
2017-12-21 07:45:38 +08:00
# include "runtime/helpers/string.h"
# include "CL/cl_ext.h"
# include "runtime/utilities/api_intercept.h"
2018-08-28 20:11:25 +08:00
# include "runtime/utilities/tag_allocator.h"
2017-12-21 07:45:38 +08:00
# include "runtime/helpers/convert_color.h"
# include "runtime/helpers/queue_helpers.h"
# include <map>
namespace OCLRT {
// Global table of create functions
CommandQueueCreateFunc commandQueueFactory [ IGFX_MAX_CORE ] = { } ;
CommandQueue * CommandQueue : : create ( Context * context ,
Device * device ,
const cl_queue_properties * properties ,
cl_int & retVal ) {
retVal = CL_SUCCESS ;
auto funcCreate = commandQueueFactory [ device - > getRenderCoreFamily ( ) ] ;
DEBUG_BREAK_IF ( nullptr = = funcCreate ) ;
return funcCreate ( context , device , properties ) ;
}
CommandQueue : : CommandQueue ( ) : CommandQueue ( nullptr , nullptr , 0 ) {
}
2018-12-06 16:21:28 +08:00
CommandQueue : : CommandQueue ( Context * context , Device * deviceId , const cl_queue_properties * properties )
: context ( context ) , device ( deviceId ) {
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 ) {
2018-11-29 18:39:10 +08:00
engine = & device - > getDefaultEngine ( ) ;
2018-11-22 20:57:10 +08:00
if ( getCommandStreamReceiver ( ) . peekTimestampPacketWriteEnabled ( ) ) {
2018-11-27 20:07:41 +08:00
timestampPacketContainer = std : : make_unique < TimestampPacketContainer > ( ) ;
2018-11-22 20:57:10 +08:00
}
2018-10-03 05:37:30 +08:00
}
2018-11-29 18:39:10 +08:00
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 - > setCurrentCmdQVirtualEvent ( false ) ;
virtualEvent - > decRefInternal ( ) ;
}
if ( device ) {
2018-11-22 20:57:10 +08:00
auto storageForAllocation = getCommandStreamReceiver ( ) . 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 ( perfConfigurationData ) {
delete perfConfigurationData ;
}
if ( this - > perfCountersEnabled ) {
device - > getPerformanceCounters ( ) - > shutdown ( ) ;
}
}
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 ( ) ;
}
}
2018-11-22 20:57:10 +08:00
CommandStreamReceiver & CommandQueue : : getCommandStreamReceiver ( ) const {
return * engine - > commandStreamReceiver ;
}
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 {
2018-11-22 20:57:10 +08:00
return getCommandStreamReceiver ( ) . getTagAddress ( ) ;
2017-12-21 07:45:38 +08:00
}
bool CommandQueue : : isCompleted ( uint32_t taskCount ) const {
uint32_t tag = getHwTag ( ) ;
DEBUG_BREAK_IF ( tag = = Event : : eventNotReady ) ;
return tag > = taskCount ;
}
2018-03-21 17:00:49 +08:00
void CommandQueue : : waitUntilComplete ( uint32_t taskCountToWait , FlushStamp flushStampToWait , bool useQuickKmdSleep ) {
2017-12-21 07:45:38 +08:00
WAIT_ENTER ( )
DBG_LOG ( LogTaskCounts , __FUNCTION__ , " Waiting for taskCount: " , taskCountToWait ) ;
DBG_LOG ( LogTaskCounts , __FUNCTION__ , " Line: " , __LINE__ , " Current taskCount: " , getHwTag ( ) ) ;
2018-11-16 19:46:49 +08:00
bool forcePowerSavingMode = this - > throttle = = QueueThrottle : : LOW ;
2018-11-26 21:04:52 +08:00
getCommandStreamReceiver ( ) . waitForTaskCountWithKmdNotifyFallback ( taskCountToWait , flushStampToWait , useQuickKmdSleep , forcePowerSavingMode ) ;
2017-12-21 07:45:38 +08:00
DEBUG_BREAK_IF ( getHwTag ( ) < taskCountToWait ) ;
latestTaskCountWaited = taskCountToWait ;
WAIT_LEAVE ( )
}
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 ) {
2017-12-20 17:20:17 +08:00
if ( this - > virtualEvent - > peekExecutionStatus ( ) < = CL_COMPLETE ) {
2017-12-21 07:45:38 +08:00
UNRECOVERABLE_IF ( this - > virtualEvent = = nullptr ) ;
2017-12-22 18:44:41 +08:00
if ( this - > virtualEvent - > isStatusCompletedByTermination ( ) = = 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 ) ;
2018-11-22 20:57:10 +08:00
taskLevel = getCommandStreamReceiver ( ) . peekTaskLevel ( ) ;
2017-12-21 07:45:38 +08:00
}
DebugManager . log ( DebugManager . flags . EventsDebugEnable . get ( ) , " isQueueBlocked taskLevel change from " , taskLevel , " to new from virtualEvent " , this - > virtualEvent , " new tasklevel " , this - > virtualEvent - > taskLevel . load ( ) ) ;
//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 ) {
return getQueueInfo < CommandQueue > ( this , paramName , paramValueSize , paramValue , paramValueSizeRet ) ;
}
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 ) ;
2018-11-22 20:57:10 +08:00
auto storageForAllocation = getCommandStreamReceiver ( ) . getInternalAllocationStorage ( ) ;
auto memoryManager = getCommandStreamReceiver ( ) . getMemoryManager ( ) ;
2017-12-21 07:45:38 +08:00
DEBUG_BREAK_IF ( nullptr = = memoryManager ) ;
if ( ! commandStream ) {
commandStream = new LinearStream ( nullptr ) ;
}
// Make sure we have enough room for any CSR additions
minRequiredSize + = CSRequirements : : minCommandQueueCommandStreamSize ;
if ( commandStream - > getAvailableSpace ( ) < minRequiredSize ) {
// If not, allocate a new block. allocate full pages
minRequiredSize = alignUp ( minRequiredSize , MemoryConstants : : pageSize ) ;
auto requiredSize = minRequiredSize + CSRequirements : : csOverfetchSize ;
2018-10-26 16:58:00 +08:00
GraphicsAllocation * allocation = storageForAllocation - > obtainReusableAllocation ( requiredSize , false ) . release ( ) ;
2017-12-21 07:45:38 +08:00
if ( ! allocation ) {
2018-12-12 01:56:37 +08:00
allocation = memoryManager - > allocateGraphicsMemoryWithProperties ( { requiredSize , GraphicsAllocation : : AllocationType : : LINEAR_STREAM } ) ;
2017-12-21 07:45:38 +08:00
}
2018-07-05 22:31:57 +08:00
allocation - > setAllocationType ( GraphicsAllocation : : AllocationType : : LINEAR_STREAM ) ;
2018-03-23 04:13:45 +08:00
2017-12-21 07:45:38 +08:00
// Deallocate the old block, if not null
auto oldAllocation = commandStream - > getGraphicsAllocation ( ) ;
if ( oldAllocation ) {
2018-10-24 20:25:04 +08:00
storageForAllocation - > storeAllocation ( std : : unique_ptr < GraphicsAllocation > ( oldAllocation ) , REUSABLE_ALLOCATION ) ;
2017-12-21 07:45:38 +08:00
}
commandStream - > replaceBuffer ( allocation - > getUnderlyingBuffer ( ) , minRequiredSize - CSRequirements : : minCommandQueueCommandStreamSize ) ;
commandStream - > replaceGraphicsAllocation ( allocation ) ;
}
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 ;
}
2018-04-19 20:11:45 +08:00
int result = memObject - > peekSharingHandler ( ) - > acquire ( memObject ) ;
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 ;
}
2017-12-21 07:45:38 +08:00
memObject - > peekSharingHandler ( ) - > release ( memObject ) ;
DEBUG_BREAK_IF ( memObject - > acquireCount < = 0 ) ;
memObject - > acquireCount - - ;
}
auto status = enqueueMarkerWithWaitList (
numEventsInWaitList ,
eventWaitList ,
oclEvent ) ;
if ( oclEvent ) {
castToObjectOrAbort < Event > ( * oclEvent ) - > setCmdType ( cmdType ) ;
}
return status ;
}
void CommandQueue : : updateFromCompletionStamp ( const CompletionStamp & completionStamp ) {
2017-12-22 23:05:10 +08:00
DEBUG_BREAK_IF ( this - > taskLevel > completionStamp . taskLevel ) ;
DEBUG_BREAK_IF ( this - > taskCount > completionStamp . taskCount ) ;
2018-01-05 19:07:47 +08:00
if ( completionStamp . taskCount ! = Event : : eventNotReady ) {
taskCount = completionStamp . taskCount ;
}
2017-12-21 07:45:38 +08:00
flushStamp - > setStamp ( completionStamp . flushStamp ) ;
this - > taskLevel = completionStamp . taskLevel ;
}
bool CommandQueue : : setPerfCountersEnabled ( bool perfCountersEnabled , cl_uint configuration ) {
DEBUG_BREAK_IF ( device = = nullptr ) ;
if ( perfCountersEnabled = = this - > perfCountersEnabled ) {
return true ;
}
auto perfCounters = device - > getPerformanceCounters ( ) ;
if ( perfCountersEnabled ) {
perfCounters - > enable ( ) ;
if ( ! perfCounters - > isAvailable ( ) ) {
perfCounters - > shutdown ( ) ;
return false ;
}
perfConfigurationData = perfCounters - > getPmRegsCfg ( configuration ) ;
if ( perfConfigurationData = = nullptr ) {
perfCounters - > shutdown ( ) ;
return false ;
}
2018-01-05 20:35:03 +08:00
InstrReadRegsCfg * pUserCounters = & perfConfigurationData - > ReadRegs ;
for ( uint32_t i = 0 ; i < pUserCounters - > RegsCount ; + + i ) {
2017-12-21 07:45:38 +08:00
perfCountersUserRegistersNumber + + ;
2018-01-05 20:35:03 +08:00
if ( pUserCounters - > Reg [ i ] . BitSize > 32 ) {
2017-12-21 07:45:38 +08:00
perfCountersUserRegistersNumber + + ;
}
}
} else {
if ( perfCounters - > isAvailable ( ) ) {
perfCounters - > shutdown ( ) ;
}
}
this - > perfCountersConfig = configuration ;
this - > perfCountersEnabled = perfCountersEnabled ;
return true ;
}
PerformanceCounters * CommandQueue : : getPerfCounters ( ) {
return device - > getPerformanceCounters ( ) ;
}
bool CommandQueue : : sendPerfCountersConfig ( ) {
return getPerfCounters ( ) - > sendPmRegsCfgCommands ( perfConfigurationData , & perfCountersRegsCfgHandle , & perfCountersRegsCfgPending ) ;
}
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 ) {
if ( memObj - > peekClMemObjType ( ) = = CL_MEM_OBJECT_BUFFER ) {
auto buffer = castToObject < Buffer > ( memObj ) ;
retVal = enqueueWriteBuffer ( buffer , CL_TRUE , unmapInfo . offset [ 0 ] , unmapInfo . size [ 0 ] , mappedPtr ,
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 ] ,
2018-09-04 21:25:29 +08:00
image - > getHostPtrRowPitch ( ) , image - > getHostPtrSlicePitch ( ) , mappedPtr ,
2018-02-18 05:26:28 +08:00
eventsRequest . numEventsInWaitList , eventsRequest . eventWaitList , eventsRequest . outEvent ) ;
bool mustCallFinish = true ;
if ( ! ( image - > getFlags ( ) & CL_MEM_USE_HOST_PTR ) ) {
mustCallFinish = true ;
} else {
mustCallFinish = ( CommandQueue : : getTaskLevelFromWaitList ( this - > taskLevel , eventsRequest . numEventsInWaitList , eventsRequest . eventWaitList ) ! = Event : : eventNotReady ) ;
}
if ( mustCallFinish ) {
finish ( true ) ;
}
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 ) {
2018-02-21 22:25:46 +08:00
void * returnPtr = ptrOffset ( transferProperties . memObj - > getBasePtrForMap ( ) ,
2018-04-04 15:29:48 +08:00
transferProperties . memObj - > calculateOffsetForMapping ( transferProperties . offset ) + transferProperties . mipPtrOffset ) ;
2018-02-18 05:26:28 +08:00
if ( ! transferProperties . memObj - > addMappedPtr ( returnPtr , transferProperties . memObj - > calculateMappedPtrLength ( transferProperties . size ) ,
2018-04-04 15:29:48 +08:00
transferProperties . mapFlags , transferProperties . size , transferProperties . offset , transferProperties . mipLevel ) ) {
2018-02-18 05:26:28 +08:00
errcodeRet = CL_INVALID_OPERATION ;
return nullptr ;
}
2018-02-09 05:59:03 +08:00
2018-02-21 22:25:46 +08:00
if ( transferProperties . memObj - > peekClMemObjType ( ) = = CL_MEM_OBJECT_BUFFER ) {
auto buffer = castToObject < Buffer > ( transferProperties . memObj ) ;
2018-02-18 05:26:28 +08:00
errcodeRet = enqueueReadBuffer ( buffer , transferProperties . blocking , transferProperties . offset [ 0 ] , transferProperties . size [ 0 ] , returnPtr ,
2018-02-09 05:59:03 +08:00
eventsRequest . numEventsInWaitList , eventsRequest . eventWaitList , eventsRequest . outEvent ) ;
} else {
2018-04-04 15:29:48 +08:00
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 ] ,
2018-09-04 21:25:29 +08:00
image - > getHostPtrRowPitch ( ) , image - > getHostPtrSlicePitch ( ) , returnPtr , eventsRequest . numEventsInWaitList ,
2018-02-13 20:20:34 +08:00
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 ) {
2018-02-18 05:26:28 +08:00
TransferProperties transferProperties ( buffer , CL_COMMAND_MAP_BUFFER , mapFlags , blockingMap ! = CL_FALSE , & offset , & size , nullptr ) ;
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 ,
2018-02-18 20:07:53 +08:00
const_cast < size_t * > ( origin ) , const_cast < size_t * > ( region ) , nullptr ) ;
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 ) {
2018-02-18 05:26:28 +08:00
TransferProperties transferProperties ( memObj , CL_COMMAND_UNMAP_MEM_OBJECT , 0 , false , nullptr , nullptr , mappedPtr ) ;
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
2018-11-22 20:57:10 +08:00
auto cmd = std : : unique_ptr < Command > ( new CommandMapUnmap ( opType , * memObj , copySize , copyOffset , readOnly , getCommandStreamReceiver ( ) , * 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 - > setCurrentCmdQVirtualEvent ( false ) ;
this - > virtualEvent - > decRefInternal ( ) ;
}
this - > virtualEvent = eventBuilder - > getEvent ( ) ;
}
2018-03-21 19:58:30 +08:00
bool CommandQueue : : setupDebugSurface ( Kernel * kernel ) {
2018-11-22 20:57:10 +08:00
auto debugSurface = getCommandStreamReceiver ( ) . getDebugSurfaceAllocation ( ) ;
2018-03-21 19:58:30 +08:00
if ( ! debugSurface ) {
2018-11-22 20:57:10 +08:00
debugSurface = getCommandStreamReceiver ( ) . allocateDebugSurface ( SipKernel : : maxDbgSurfaceSize ) ;
2018-03-21 19:58:30 +08:00
}
DEBUG_BREAK_IF ( ! kernel - > requiresSshForBuffers ( ) ) ;
auto surfaceState = ptrOffset ( reinterpret_cast < uintptr_t * > ( kernel - > getSurfaceStateHeap ( ) ) ,
kernel - > getKernelInfo ( ) . patchInfo . pAllocateSystemThreadSurface - > Offset ) ;
void * addressToPatch = reinterpret_cast < void * > ( debugSurface - > getGpuAddress ( ) ) ;
size_t sizeToPatch = debugSurface - > getUnderlyingBufferSize ( ) ;
2018-06-11 20:58:35 +08:00
Buffer : : setSurfaceState ( device , surfaceState , sizeToPatch , addressToPatch , debugSurface ) ;
2018-03-21 19:58:30 +08:00
return true ;
}
2018-04-26 16:01:01 +08:00
IndirectHeap & CommandQueue : : getIndirectHeap ( IndirectHeap : : Type heapType , size_t minRequiredSize ) {
2018-11-22 20:57:10 +08:00
return getCommandStreamReceiver ( ) . 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 ) {
2018-11-22 20:57:10 +08:00
getCommandStreamReceiver ( ) . 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 ) {
2018-11-22 20:57:10 +08:00
getCommandStreamReceiver ( ) . releaseIndirectHeap ( heapType ) ;
2018-04-05 21:12:28 +08:00
}
2018-04-26 16:01:01 +08:00
2018-08-12 00:12:28 +08:00
void CommandQueue : : dispatchAuxTranslation ( MultiDispatchInfo & multiDispatchInfo , BuffersForAuxTranslation & buffersForAuxTranslation ,
AuxTranslationDirection auxTranslationDirection ) {
2018-08-22 19:57:21 +08:00
auto & builder = getDevice ( ) . getExecutionEnvironment ( ) - > getBuiltIns ( ) - > getBuiltinDispatchInfoBuilder ( EBuiltInOps : : AuxTranslation , getContext ( ) , getDevice ( ) ) ;
2018-08-12 00:12:28 +08:00
BuiltinDispatchInfoBuilder : : BuiltinOpParams dispatchParams ;
dispatchParams . buffersForAuxTranslation = & buffersForAuxTranslation ;
dispatchParams . auxTranslationDirection = auxTranslationDirection ;
builder . buildDispatchInfos ( multiDispatchInfo , dispatchParams ) ;
}
2018-08-28 20:11:25 +08:00
2018-10-03 05:37:30 +08:00
void CommandQueue : : obtainNewTimestampPacketNodes ( size_t numberOfNodes , TimestampPacketContainer & previousNodes ) {
2018-11-27 20:07:41 +08:00
auto allocator = getCommandStreamReceiver ( ) . getTimestampPacketAllocator ( ) ;
2018-08-28 20:11:25 +08:00
2018-10-03 05:37:30 +08:00
previousNodes . swapNodes ( * timestampPacketContainer ) ;
previousNodes . resolveDependencies ( isOOQEnabled ( ) ) ;
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
}
2018-11-09 00:22:21 +08:00
} // namespace OCLRT