blob: 7198b6bf2d19133d2ce7cef7136da650d9c65ff0 [file] [log] [blame]
/*
* Copyright (c) 2017, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
//!
//! \file cm_task_internal.cpp
//! \brief Contains Class CmTaskInternal definitions
//!
#include "cm_task_internal.h"
#include "cm_kernel_rt.h"
#include "cm_mem.h"
#include "cm_event_rt.h"
#include "cm_device_rt.h"
#include "cm_kernel_data.h"
#include "cm_thread_space_rt.h"
#include "cm_group_space.h"
#include "cm_vebox_rt.h"
#include "cm_vebox_data.h"
#include "cm_queue_rt.h"
#include "cm_surface_manager.h"
#include "cm_buffer_rt.h"
#include "cm_surface_2d_rt.h"
#include "cm_surface_2d_up_rt.h"
#include "cm_surface_3d_rt.h"
#include "cm_surface_vme.h"
#include "cm_surface_sampler.h"
#include "cm_surface_sampler8x8.h"
namespace CMRT_UMD
{
//*-----------------------------------------------------------------------------
//| Purpose: Create Task internal
//| Returns: Result of the operation.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::Create(const uint32_t kernelCount, const uint32_t totalThreadCount,
CmKernelRT* kernelArray[], const CmThreadSpaceRT* threadSpace,
CmDeviceRT* device, const uint64_t syncBitmap, CmTaskInternal*& task,
const uint64_t conditionalEndBitmap,
PCM_HAL_CONDITIONAL_BB_END_INFO conditionalEndInfo)
{
int32_t result = CM_SUCCESS;
task = new (std::nothrow) CmTaskInternal(kernelCount, totalThreadCount, kernelArray, device,
syncBitmap, conditionalEndBitmap, conditionalEndInfo,
nullptr);
if( task )
{
result = task->Initialize(threadSpace, false);
if( result != CM_SUCCESS )
{
CmTaskInternal::Destroy( task);
}
}
else
{
CM_ASSERTMESSAGE("Error: Failed to create CmTaskInternal due to out of system memory.");
result = CM_OUT_OF_HOST_MEMORY;
}
return result;
}
//*-----------------------------------------------------------------------------
//| Purpose: Create Task internal with Thread Group Space
//| Returns: Result of the operation.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::Create( const uint32_t kernelCount, const uint32_t totalThreadCount,
CmKernelRT* kernelArray[], const CmThreadGroupSpace* threadGroupSpace,
CmDeviceRT* device, const uint64_t syncBitmap, CmTaskInternal*& task,
const uint64_t conditionalEndBitmap,
PCM_HAL_CONDITIONAL_BB_END_INFO conditionalEndInfo,
const CM_EXECUTION_CONFIG* krnExecCfg)
{
int32_t result = CM_SUCCESS;
task = new (std::nothrow) CmTaskInternal(kernelCount, totalThreadCount, kernelArray, device,
syncBitmap, conditionalEndBitmap, conditionalEndInfo,
krnExecCfg);
if( task )
{
result = task->Initialize(threadGroupSpace);
if( result != CM_SUCCESS )
{
CmTaskInternal::Destroy( task);
}
}
else
{
CM_ASSERTMESSAGE("Error: Failed to create CmTaskInternal due to out of system memory.");
result = CM_OUT_OF_HOST_MEMORY;
}
return result;
}
int32_t CmTaskInternal::Create( CmDeviceRT* device, CmVeboxRT* vebox, CmTaskInternal*& task )
{
int32_t result = CM_SUCCESS;
task = new (std::nothrow) CmTaskInternal(0, 0, nullptr, device, CM_NO_KERNEL_SYNC,
CM_NO_CONDITIONAL_END, nullptr, nullptr);
if( task )
{
result = task->Initialize(vebox);
if( result != CM_SUCCESS )
{
CmTaskInternal::Destroy( task);
}
}
else
{
CM_ASSERTMESSAGE("Error: Failed to create CmTaskInternal due to out of system memory.");
result = CM_OUT_OF_HOST_MEMORY;
}
return result;
}
//*-----------------------------------------------------------------------------
//| Purpose: Create Task internal with hints
//| Returns: Result of the operation.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::Create(const uint32_t kernelCount, const uint32_t totalThreadCount,
CmKernelRT* kernelArray[], CmTaskInternal*& task,
uint32_t numGeneratedTasks, bool isLastTask, uint32_t hints,
CmDeviceRT* device)
{
int32_t result = CM_SUCCESS;
task = new (std::nothrow) CmTaskInternal(kernelCount, totalThreadCount, kernelArray, device,
CM_NO_KERNEL_SYNC, CM_NO_CONDITIONAL_END, nullptr, nullptr);
if ( task )
{
result = task->Initialize(hints, numGeneratedTasks, isLastTask);
if ( result != CM_SUCCESS )
{
CmTaskInternal::Destroy( task );
}
}
else
{
CM_ASSERTMESSAGE("Error: Failed to create CmTaskInternal due to out of system memory.");
result = CM_OUT_OF_HOST_MEMORY;
}
return result;
}
//*-----------------------------------------------------------------------------
//| Purpose: Destroy Task internal
//| Returns: None.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::Destroy( CmTaskInternal* &task )
{
CmSafeDelete( task );
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Constructor of CmTaskInternal
//| Returns: None.
//*-----------------------------------------------------------------------------
CmTaskInternal::CmTaskInternal(const uint32_t kernelCount, const uint32_t totalThreadCount,
CmKernelRT* kernelArray[], CmDeviceRT* device,
const uint64_t syncBitmap, const uint64_t conditionalEndBitmap,
PCM_HAL_CONDITIONAL_BB_END_INFO conditionalEndInfo,
const CM_EXECUTION_CONFIG* krnExecCfg) :
m_kernels( kernelCount ),
m_kernelData( kernelCount ),
m_kernelCount( kernelCount ),
m_totalThreadCount(totalThreadCount),
m_taskEvent( nullptr ),
m_isThreadSpaceCreated(false),
m_isThreadCoordinatesExisted(false),
m_threadSpaceWidth(0),
m_threadSpaceHeight(0),
m_threadSpaceDepth(0),
m_threadCoordinates(nullptr),
m_dependencyPattern(CM_NONE_DEPENDENCY),
m_walkingPattern(CM_WALK_DEFAULT),
m_mediaWalkerParamsSet( false ),
m_dependencyVectorsSet( false ),
m_dependencyMasks( nullptr ),
m_mediaWalkerGroupSelect(CM_MW_GROUP_NONE),
m_isThreadGroupSpaceCreated(false),
m_groupSpaceWidth(0),
m_groupSpaceHeight(0),
m_groupSpaceDepth(0),
m_slmSize(0),
m_spillMemUsed(0),
m_colorCountMinusOne( 0 ),
m_hints(0),
m_numTasksGenerated( 0 ),
m_isLastTask( false ),
m_ui64SyncBitmap (syncBitmap ),
m_ui64ConditionalEndBitmap(conditionalEndBitmap),
m_cmDevice( device ),
m_surfaceArray (nullptr),
m_isSurfaceUpdateDone(false),
m_taskType(CM_TASK_TYPE_DEFAULT),
m_mediaStatePtr( nullptr )
{
m_kernelSurfInfo.kernelNum = 0;
m_kernelSurfInfo.surfEntryInfosArray = nullptr;
m_kernelCurbeOffsetArray = MOS_NewArray(uint32_t, kernelCount);
CM_ASSERT(m_kernelCurbeOffsetArray != nullptr);
for( uint32_t i = 0 ; i < kernelCount; i ++ )
{
m_kernels.SetElement( i, kernelArray[ i ] );
m_kernelData.SetElement( i, nullptr );
}
CmSafeMemSet( &m_walkingParameters, 0, sizeof(m_walkingParameters));
CmSafeMemSet( &m_dependencyVectors, 0, sizeof(m_dependencyVectors));
CmSafeMemSet( &m_taskConfig, 0, sizeof(m_taskConfig));
if ( m_kernelCurbeOffsetArray != nullptr )
{
CmSafeMemSet( m_kernelCurbeOffsetArray, 0, sizeof(uint32_t) * kernelCount );
}
CmSafeMemSet(&m_taskProfilingInfo, 0, sizeof(m_taskProfilingInfo));
if (conditionalEndInfo != nullptr)
{
CmSafeMemCopy(&m_conditionalEndInfo, conditionalEndInfo, sizeof(m_conditionalEndInfo));
}
else
{
CmSafeMemSet(&m_conditionalEndInfo, 0, sizeof(m_conditionalEndInfo));
}
CmSafeMemSet(&m_veboxParam, 0, sizeof(m_veboxParam));
CmSafeMemSet(&m_veboxState, 0, sizeof(m_veboxState));
CmSafeMemSet(&m_veboxSurfaceData, 0, sizeof(m_veboxSurfaceData));
CmSafeMemSet(&m_powerOption, 0, sizeof(m_powerOption));
if (krnExecCfg != nullptr)
{
CmSafeMemCopy(&m_krnExecCfg, krnExecCfg, sizeof(m_krnExecCfg));
}
}
//*-----------------------------------------------------------------------------
//| Purpose: Destructor of CmTaskInternal
//| Returns: None.
//*-----------------------------------------------------------------------------
CmTaskInternal::~CmTaskInternal( void )
{
//Write Event Infos
VtuneWriteEventInfo();
//Release Profiling Info
VtuneReleaseProfilingInfo();
for( uint32_t i = 0; i < m_kernelCount; i ++ )
{
CmKernelRT *kernel = (CmKernelRT*)m_kernels.GetElement(i);
CmKernelData* kernelData = (CmKernelData*)m_kernelData.GetElement( i );
if(kernel && kernelData)
{
kernel->ReleaseKernelData(kernelData);
CmKernel *kernelBase = kernel;
m_cmDevice->DestroyKernel(kernelBase);
}
}
m_kernelData.Delete();
m_kernels.Delete();
MosSafeDeleteArray(m_kernelCurbeOffsetArray);
if( m_taskEvent )
{
CmEvent *eventBase = m_taskEvent;
CmQueueRT *cmQueue = nullptr;
m_taskEvent->GetQueue(cmQueue);
if (cmQueue)
{
cmQueue->DestroyEvent(eventBase); // need to update the m_EventArray
}
}
if(m_threadCoordinates){
for (uint32_t i=0; i<m_kernelCount; i++)
{
if (m_threadCoordinates[i])
{
MosSafeDeleteArray(m_threadCoordinates[i]);
}
}
MosSafeDeleteArray( m_threadCoordinates );
}
if( m_dependencyMasks )
{
for( uint32_t i = 0; i < m_kernelCount; ++i )
{
MosSafeDeleteArray(m_dependencyMasks[i]);
}
MosSafeDeleteArray( m_dependencyMasks );
}
if((m_kernelSurfInfo.kernelNum != 0)&&(m_kernelSurfInfo.surfEntryInfosArray != nullptr))
{
ClearKernelSurfInfo();
}
MosSafeDeleteArray(m_surfaceArray);
}
//*-----------------------------------------------------------------------------
//| Purpose: Initialize Class CmTaskInternal
//| Returns: None.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::Initialize(const CmThreadSpaceRT* threadSpace, bool isWithHints)
{
uint32_t totalCurbeSize = 0;
uint32_t surfacePoolSize = 0;
uint32_t totalKernelBinarySize = 0;
uint32_t kernelCurbeSize = 0;
uint32_t kernelPayloadSize = 0;
CmSurfaceManager* surfaceMgr = nullptr;
int32_t result = CM_SUCCESS;
CM_HAL_MAX_VALUES* halMaxValues = nullptr;
CM_HAL_MAX_VALUES_EX* halMaxValuesEx = nullptr;
m_cmDevice->GetHalMaxValues( halMaxValues, halMaxValuesEx );
if (m_cmDevice->IsPrintEnable())
{
SurfaceIndex *printBufferIndex = nullptr;
m_cmDevice->GetPrintBufferIndex(printBufferIndex);
CM_ASSERT(printBufferIndex);
for (uint32_t i = 0; i < m_kernelCount; i++)
{
CmKernelRT* kernel = (CmKernelRT*)m_kernels.GetElement(i);
if(kernel == nullptr)
{
CM_ASSERTMESSAGE("Error: Invalid kernel pointer.");
return CM_FAILURE;
}
if(FAILED(kernel->SetStaticBuffer(CM_PRINTF_STATIC_BUFFER_ID, printBufferIndex)))
{
CM_ASSERTMESSAGE("Error: Failed to set static buffer.");
return CM_FAILURE;
}
}
}
m_cmDevice->GetSurfaceManager( surfaceMgr );
CM_CHK_NULL_RETURN_CMERROR(surfaceMgr);
surfacePoolSize = surfaceMgr->GetSurfacePoolSize();
m_surfaceArray = MOS_NewArray(bool, surfacePoolSize);
if (!m_surfaceArray)
{
CM_ASSERTMESSAGE("Error: Out of system memory.");
return CM_FAILURE;
}
CmSafeMemSet( m_surfaceArray, 0, surfacePoolSize * sizeof( bool ) );
for( uint32_t i = 0; i < m_kernelCount; i ++ )
{
CmKernelRT* kernel = (CmKernelRT*)m_kernels.GetElement( i );
if(kernel == nullptr)
{
CM_ASSERTMESSAGE("Error: Invalid kernel pointer.");
return CM_FAILURE;
}
uint32_t totalSize = 0;
CmKernelData* kernelData = nullptr;
if ( isWithHints )
{
CmThreadSpaceRT* kernelThreadSpace = nullptr;
kernel->GetThreadSpace(kernelThreadSpace);
if( kernelThreadSpace )
{
for(uint32_t j = i; j > 0; --j)
{
uint32_t width, height, myAdjY;
CmKernelRT* tmpKernel = (CmKernelRT*)m_kernels.GetElement( j-1 );
if( !tmpKernel )
{
CM_ASSERTMESSAGE("Error: Invalid kernel pointer.");
return CM_FAILURE;
}
tmpKernel->GetThreadSpace(kernelThreadSpace);
kernelThreadSpace->GetThreadSpaceSize(width, height);
myAdjY = kernel->GetAdjustedYCoord();
kernel->SetAdjustedYCoord(myAdjY + height);
}
}
}
if (threadSpace == nullptr)
{
CmThreadSpaceRT* kernelThreadSpace = nullptr;
kernel->GetThreadSpace(kernelThreadSpace);
if (kernelThreadSpace)
{
kernelThreadSpace->SetDependencyArgToKernel(kernel);
}
}
if (threadSpace != nullptr)
{
threadSpace->SetDependencyArgToKernel(kernel);
}
kernel->CollectKernelSurface();
result = kernel->CreateKernelData( kernelData, totalSize, threadSpace );
if( (kernelData == nullptr) || (result != CM_SUCCESS))
{
CM_ASSERTMESSAGE("Error: Failed to create kernel data.");
CmKernelData::Destroy( kernelData );
return result;
}
kernel->GetSizeInPayload( kernelPayloadSize );
kernel->GetSizeInCurbe( kernelCurbeSize );
if ( ( kernelCurbeSize + kernelPayloadSize ) > halMaxValues->maxArgByteSizePerKernel )
{ //Failed, exceed the maximum of inline data
CM_ASSERTMESSAGE("Error: Invalid kernel arg size.");
return CM_EXCEED_KERNEL_ARG_SIZE_IN_BYTE;
}
else
{
kernelCurbeSize = kernel->GetAlignedCurbeSize( kernelCurbeSize );
totalCurbeSize += kernelCurbeSize;
}
m_kernelCurbeOffsetArray[ i ] = totalCurbeSize - kernelCurbeSize;
m_kernelData.SetElement( i, kernelData );
totalKernelBinarySize += kernel->GetKernelGenxBinarySize();
totalKernelBinarySize += CM_KERNEL_BINARY_PADDING_SIZE; //Padding is necessary after kernel binary to avoid page fault issue
bool *surfArray = nullptr;
kernel->GetKernelSurfaces(surfArray);
for (uint32_t j = 0; j < surfacePoolSize; j ++)
{
m_surfaceArray[j] |= surfArray[j];
}
kernel->ResetKernelSurfaces();
PCM_CONTEXT_DATA cmData = ( PCM_CONTEXT_DATA )m_cmDevice->GetAccelData();
PCM_HAL_STATE state = cmData->cmHalState;
PRENDERHAL_MEDIA_STATE mediaStatePtr = state->pfnGetMediaStatePtrForKernel( state, kernel );
if ( ( mediaStatePtr != nullptr ) && ( m_mediaStatePtr == nullptr ) )
{
m_mediaStatePtr = mediaStatePtr;
}
else if ( ( mediaStatePtr != nullptr ) && ( m_mediaStatePtr != nullptr ) )
{
CM_ASSERTMESSAGE( "Error: More than one media state heap are used in one task! User-provided state heap error.\n" );
return CM_INVALID_ARG_VALUE;
}
}
if (totalKernelBinarySize > halMaxValues->maxKernelBinarySize * halMaxValues->maxKernelsPerTask)
{
CM_ASSERTMESSAGE("Error: Invalid kernel arg size.");
return CM_EXCEED_MAX_KERNEL_SIZE_IN_BYTE;
}
if (threadSpace)
{
if(FAILED(this->CreateThreadSpaceData(threadSpace)))
{
CM_ASSERTMESSAGE("Error: Failed to create thread space data.");
return CM_FAILURE;
}
m_isThreadSpaceCreated = true;
}
UpdateSurfaceStateOnTaskCreation();
m_taskType = CM_INTERNAL_TASK_WITH_THREADSPACE;
if ( m_cmDevice->CheckGTPinEnabled())
{
AllocateKernelSurfInfo();
}
this->VtuneInitProfilingInfo(threadSpace);
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Initialize Class CmTaskInternal with thread group space
//| Returns: None.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::Initialize(const CmThreadGroupSpace* threadGroupSpace)
{
uint32_t totalCurbeSize = 0;
uint32_t surfacePoolSize = 0;
uint32_t totalKernelBinarySize = 0;
uint32_t kernelCurbeSize = 0;
uint32_t kernelPayloadSize = 0;
CmSurfaceManager* surfaceMgr = nullptr;
CM_HAL_MAX_VALUES* halMaxValues = nullptr;
CM_HAL_MAX_VALUES_EX* halMaxValuesEx = nullptr;
m_cmDevice->GetHalMaxValues( halMaxValues, halMaxValuesEx );
m_cmDevice->GetSurfaceManager( surfaceMgr );
CM_CHK_NULL_RETURN_CMERROR( surfaceMgr );
surfacePoolSize = surfaceMgr->GetSurfacePoolSize();
m_surfaceArray = MOS_NewArray(bool, surfacePoolSize);
if (!m_surfaceArray)
{
CM_ASSERTMESSAGE("Error: Out of system memory.");
return CM_OUT_OF_HOST_MEMORY;
}
CmSafeMemSet( m_surfaceArray, 0, surfacePoolSize * sizeof( bool ) );
if (m_cmDevice->IsPrintEnable())
{
SurfaceIndex *printBufferIndex = nullptr;
m_cmDevice->GetPrintBufferIndex(printBufferIndex);
CM_ASSERT(printBufferIndex);
for (uint32_t i = 0; i < m_kernelCount; i++)
{
CmKernelRT* kernel = (CmKernelRT*)m_kernels.GetElement(i);
if(kernel == nullptr)
{
CM_ASSERTMESSAGE("Error: Invalid kernel pointer.");
return CM_FAILURE;
}
if(FAILED(kernel->SetStaticBuffer(CM_PRINTF_STATIC_BUFFER_ID, printBufferIndex)))
{
CM_ASSERTMESSAGE("Error: Failed to set static buffer.");
return CM_FAILURE;
}
}
}
for( uint32_t i = 0; i < m_kernelCount; i ++ )
{
CmKernelRT* kernel = (CmKernelRT*)m_kernels.GetElement( i );
if(kernel == nullptr)
{
CM_ASSERTMESSAGE("Error: Invalid kernel pointer.");
return CM_FAILURE;
}
kernel->CollectKernelSurface();
uint32_t totalSize = 0;
CmKernelData* kernelData = nullptr;
int32_t result = kernel->CreateKernelData( kernelData, totalSize, threadGroupSpace );
if(result != CM_SUCCESS)
{
CM_ASSERTMESSAGE("Error: Failed to create kernel data.");
CmKernelData::Destroy( kernelData );
return result;
}
kernelData->SetKernelDataSize(totalSize);
kernel->GetSizeInPayload(kernelPayloadSize);
PCM_HAL_KERNEL_PARAM halKernelParam = kernelData->GetHalCmKernelData();
if (halKernelParam->crossThreadConstDataLen + halKernelParam->curbeSizePerThread + kernelPayloadSize
> halMaxValues->maxArgByteSizePerKernel)
{ //Failed, exceed the maximum of inline data
CM_ASSERTMESSAGE("Error: Invalid kernel arg size.");
return CM_EXCEED_KERNEL_ARG_SIZE_IN_BYTE;
}
else
{
kernel->GetSizeInCurbe(kernelCurbeSize);
kernelCurbeSize = kernel->GetAlignedCurbeSize(kernelCurbeSize);
totalCurbeSize += kernelCurbeSize;
}
m_kernelCurbeOffsetArray[ i ] = totalCurbeSize - kernelCurbeSize;
m_kernelData.SetElement( i, kernelData );
m_slmSize = kernel->GetSLMSize();
m_spillMemUsed = kernel->GetSpillMemUsed();
totalKernelBinarySize += kernel->GetKernelGenxBinarySize();
totalKernelBinarySize += CM_KERNEL_BINARY_PADDING_SIZE;
bool *surfArray = nullptr;
kernel->GetKernelSurfaces(surfArray);
for (uint32_t j = 0; j < surfacePoolSize; j ++)
{
m_surfaceArray[j] |= surfArray[j];
}
kernel->ResetKernelSurfaces();
PCM_CONTEXT_DATA cmData = ( PCM_CONTEXT_DATA )m_cmDevice->GetAccelData();
PCM_HAL_STATE state = cmData->cmHalState;
PRENDERHAL_MEDIA_STATE mediaStatePtr = state->pfnGetMediaStatePtrForKernel( state, kernel );
if ( ( mediaStatePtr != nullptr ) && ( m_mediaStatePtr == nullptr ) )
{
m_mediaStatePtr = mediaStatePtr;
}
else if ( ( mediaStatePtr != nullptr ) && ( m_mediaStatePtr != nullptr ) )
{
CM_ASSERTMESSAGE("Error: More than one media state heap are used in one task! User-provided state heap error.\n" );
return CM_INVALID_ARG_VALUE;
}
}
if( totalKernelBinarySize > halMaxValues->maxKernelBinarySize * halMaxValues->maxKernelsPerTask)
{
CM_ASSERTMESSAGE("Error: Invalid kernel arg size.");
return CM_EXCEED_MAX_KERNEL_SIZE_IN_BYTE;
}
UpdateSurfaceStateOnTaskCreation();
m_taskType = CM_INTERNAL_TASK_WITH_THREADGROUPSPACE;
if (threadGroupSpace)
{
threadGroupSpace->GetThreadGroupSpaceSize(m_threadSpaceWidth, m_threadSpaceHeight,
m_threadSpaceDepth, m_groupSpaceWidth,
m_groupSpaceHeight, m_groupSpaceDepth);
m_isThreadGroupSpaceCreated = true;
}
if ( m_cmDevice->CheckGTPinEnabled())
{
AllocateKernelSurfInfo();
}
this->VtuneInitProfilingInfo(threadGroupSpace);
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Initialize Class CmTaskInternal
//| Returns: None.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::Initialize(CmVeboxRT* vebox)
{
int32_t result = CM_SUCCESS;
CmSurfaceManager* surfaceMgr = nullptr;
uint32_t surfacePoolSize = 0;
m_cmDevice->GetSurfaceManager( surfaceMgr );
CM_CHK_NULL_RETURN_CMERROR( surfaceMgr );
surfacePoolSize = surfaceMgr->GetSurfacePoolSize();
m_surfaceArray = MOS_NewArray(bool, surfacePoolSize);
if (!m_surfaceArray)
{
CM_ASSERTMESSAGE("Error: Out of system memory.");
return CM_FAILURE;
}
CmSafeMemSet( m_surfaceArray, 0, surfacePoolSize * sizeof( bool ) );
CmBufferUP *paramBuffer = nullptr;
paramBuffer = vebox->GetParam();
m_veboxState = vebox->GetState();
m_veboxParam = paramBuffer;
m_taskType = CM_INTERNAL_TASK_VEBOX;
//Update used surfaces
for (int i = 0; i < VEBOX_SURFACE_NUMBER; i++)
{
CmSurface2DRT* surf = nullptr;
vebox->GetSurface(i, surf);
if (surf)
{
uint32_t surfaceHandle = 0;
SurfaceIndex* surfIndex = nullptr;
surf->GetIndex(surfIndex);
surf->GetHandle(surfaceHandle);
m_surfaceArray[surfIndex->get_data()] = true;
m_veboxSurfaceData.surfaceEntry[i].surfaceIndex = (uint16_t)surfaceHandle;
m_veboxSurfaceData.surfaceEntry[i].surfaceCtrlBits = vebox->GetSurfaceControlBits(i);
}
else
{
m_veboxSurfaceData.surfaceEntry[i].surfaceIndex = CM_INVALID_INDEX;
m_veboxSurfaceData.surfaceEntry[i].surfaceCtrlBits = CM_INVALID_INDEX;
}
}
UpdateSurfaceStateOnTaskCreation();
return result;
}
//*-----------------------------------------------------------------------------
//| Purpose: Initialize Class CmTaskInternal with hints
//| Returns: Result of the operation
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::Initialize(uint32_t hints, uint32_t numTasksGenerated, bool isLastTask)
{
CmThreadSpaceRT* threadSpace = nullptr;
int32_t result = CM_SUCCESS;
// use ThreadSpace Initialize function to create kernel data
result = this->Initialize(threadSpace, true);
// set hints in task
m_hints = hints;
m_numTasksGenerated = numTasksGenerated;
m_isLastTask = isLastTask;
// set task type to be EnqueueWithHints
m_taskType = CM_INTERNAL_TASK_ENQUEUEWITHHINTS;
return result;
}
//*-----------------------------------------------------------------------------
//| Purpose: Get Kernel Count
//| Returns: CM_SUCCESS.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetKernelCount( uint32_t& count )
{
count = m_kernelCount;
return CM_SUCCESS;
}
int32_t CmTaskInternal::GetTaskSurfaces( bool *&surfArray )
{
surfArray = m_surfaceArray;
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Geth Kernel from the Kernel array
//| Returns: Result of operation.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetKernel( const uint32_t index, CmKernelRT* & kernel )
{
kernel = nullptr;
if( index < m_kernels.GetSize() )
{
kernel = (CmKernelRT*)m_kernels.GetElement( index );
return CM_SUCCESS;
}
else
{
return CM_FAILURE;
}
}
//*-----------------------------------------------------------------------------
//| Purpose: Geth Kernel data by kernel's index
//| Returns: Result of operation.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetKernelData( const uint32_t index, CmKernelData* & kernelData )
{
kernelData = nullptr;
if( index < m_kernelData.GetSize() )
{
kernelData = (CmKernelData*)m_kernelData.GetElement( index );
return CM_SUCCESS;
}
else
{
return CM_FAILURE;
}
}
//*-----------------------------------------------------------------------------
//| Purpose: Geth Kernel data size by kernel's index
//| Returns: Result of operation.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetKernelDataSize( const uint32_t index, uint32_t & size )
{
size = 0;
CmKernelData* kernelData = nullptr;
if( index < m_kernelData.GetSize() )
{
kernelData = (CmKernelData*)m_kernelData.GetElement( index );
if (kernelData == nullptr)
{
CM_ASSERTMESSAGE("Error: Invalid kernel data.");
return CM_FAILURE;
}
size = kernelData->GetKernelDataSize();
return CM_SUCCESS;
}
else
{
return CM_FAILURE;
}
}
//*-----------------------------------------------------------------------------
//| Purpose: Get kernel's curbe offset
//| Returns: Result of operation.
//*-----------------------------------------------------------------------------
uint32_t CmTaskInternal::GetKernelCurbeOffset( const uint32_t index )
{
return ( uint32_t ) m_kernelCurbeOffsetArray[ index ];
}
//*-----------------------------------------------------------------------------
//| Purpose: Set task event, need add refcount hehe.
//| Returns: Result of operation.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::SetTaskEvent( CmEventRT* event )
{
m_taskEvent = event;
// add refCount
m_taskEvent->Acquire();
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Get the task event
//| Returns: Result of operation.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetTaskEvent( CmEventRT* & event )
{
event = m_taskEvent;
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Get the task's status
//| Returns: Result of operation.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetTaskStatus(CM_STATUS & taskStatus)
{
if(m_taskEvent == nullptr)
{
return CM_FAILURE;
}
return m_taskEvent->GetStatusNoFlush(taskStatus);
}
//*-----------------------------------------------------------------------------
//| Purpose: Record CPU ticks for Flush Time
//| Returns: Result of operation.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::VtuneSetFlushTime()
{
if(!m_cmDevice->IsVtuneLogOn())
{ // return directly if ETW log is off
return CM_SUCCESS;
}
MOS_QueryPerformanceCounter((uint64_t*)&m_taskProfilingInfo.flushTime.QuadPart);
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Initialize Profiling Information for Media Pipeline
//| Returns: Result of operation.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::VtuneInitProfilingInfo(const CmThreadSpaceRT *perTaskThreadSpace)
{
CmKernelRT *cmKernel = nullptr;
CmThreadSpaceRT *perKernelThreadSpace = nullptr;
uint32_t threadSpaceWidth = 0;
uint32_t threadSpaceHeight = 0;
int32_t hr = CM_SUCCESS;
if(!m_cmDevice->IsVtuneLogOn())
{ // return directly if ETW log is off
return CM_SUCCESS;
}
CmSafeMemSet(&m_taskProfilingInfo, 0, sizeof(m_taskProfilingInfo));
m_taskProfilingInfo.kernelCount = m_kernelCount;
m_taskProfilingInfo.threadID = CmGetCurThreadId(); // Get Thread ID
MOS_QueryPerformanceCounter((uint64_t*)&m_taskProfilingInfo.enqueueTime.QuadPart); // Get Enqueue Time
// Currently, the Kernel/ThreadSpace/ThreadGroupSpace could not be deleted before task finished.
m_taskProfilingInfo.kernelNames = MOS_NewArray(char, (CM_MAX_KERNEL_NAME_SIZE_IN_BYTE * m_kernelCount));
CM_CHK_NULL_GOTOFINISH_CMERROR(m_taskProfilingInfo.kernelNames);
m_taskProfilingInfo.localWorkWidth = MOS_NewArray(uint32_t, m_kernelCount);
CM_CHK_NULL_GOTOFINISH_CMERROR(m_taskProfilingInfo.localWorkWidth);
m_taskProfilingInfo.localWorkHeight = MOS_NewArray(uint32_t, m_kernelCount);
CM_CHK_NULL_GOTOFINISH_CMERROR(m_taskProfilingInfo.localWorkHeight);
m_taskProfilingInfo.globalWorkWidth = MOS_NewArray(uint32_t, m_kernelCount);
CM_CHK_NULL_GOTOFINISH_CMERROR(m_taskProfilingInfo.globalWorkWidth);
m_taskProfilingInfo.globalWorkHeight = MOS_NewArray(uint32_t, m_kernelCount);
CM_CHK_NULL_GOTOFINISH_CMERROR(m_taskProfilingInfo.globalWorkHeight);
for (uint32_t i = 0; i < m_kernelCount; i++)
{
CM_CHK_CMSTATUS_GOTOFINISH(GetKernel(i, cmKernel));
CM_CHK_NULL_GOTOFINISH_CMERROR(cmKernel);
//Copy Kernel Name
MOS_SecureStrcpy(m_taskProfilingInfo.kernelNames + m_taskProfilingInfo.kernelNameLen,
CM_MAX_KERNEL_NAME_SIZE_IN_BYTE, cmKernel->GetName());
//Add Kernel Name Length
m_taskProfilingInfo.kernelNameLen += strlen(cmKernel->GetName()) + 1;
CM_CHK_CMSTATUS_GOTOFINISH(cmKernel->GetThreadSpace(perKernelThreadSpace));
if (perTaskThreadSpace)
{
//Per Task Thread Space Exists
m_taskProfilingInfo.localWorkWidth[i] = m_threadSpaceWidth;
m_taskProfilingInfo.localWorkHeight[i] = m_threadSpaceHeight;
m_taskProfilingInfo.globalWorkWidth[i] = m_threadSpaceWidth;
m_taskProfilingInfo.globalWorkHeight[i] = m_threadSpaceHeight;
}
else if (perKernelThreadSpace)
{
//Fill each threads Space's info
perKernelThreadSpace->GetThreadSpaceSize(threadSpaceWidth, threadSpaceHeight);
m_taskProfilingInfo.localWorkWidth[i] = threadSpaceWidth;
m_taskProfilingInfo.localWorkHeight[i] = threadSpaceHeight;
m_taskProfilingInfo.globalWorkWidth[i] = threadSpaceWidth;
m_taskProfilingInfo.globalWorkHeight[i] = threadSpaceHeight;
}
else
{
//Fill the thread count
uint32_t threadCount = 0;
cmKernel->GetThreadCount(threadCount);
m_taskProfilingInfo.localWorkWidth[i] = threadCount;
m_taskProfilingInfo.localWorkHeight[i] = 1;
m_taskProfilingInfo.globalWorkWidth[i] = threadCount;
m_taskProfilingInfo.globalWorkHeight[i] = 1;
}
}
finish:
if (hr != CM_SUCCESS)
{
MosSafeDeleteArray(m_taskProfilingInfo.kernelNames);
MosSafeDeleteArray(m_taskProfilingInfo.localWorkWidth);
MosSafeDeleteArray(m_taskProfilingInfo.localWorkHeight);
MosSafeDeleteArray(m_taskProfilingInfo.globalWorkWidth);
MosSafeDeleteArray(m_taskProfilingInfo.globalWorkHeight);
}
return hr;
}
//*-----------------------------------------------------------------------------
//| Purpose: Initialize Profiling Information
//| Returns: Result of operation.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::VtuneInitProfilingInfo(const CmThreadGroupSpace *perTaskThreadGroupSpace)
{
CmKernelRT *cmKernel = nullptr;
CmThreadGroupSpace *perKernelGroupSpace = nullptr;
uint32_t threadSpaceWidth = 0;
uint32_t threadSpaceHeight = 0;
uint32_t threadSpaceDepth = 0;
uint32_t threadGroupSpaceWidth = 0;
uint32_t threadGroupSpaceHeight = 0;
uint32_t threadGroupSpaceDepth = 0;
int32_t hr = CM_SUCCESS;
if(!m_cmDevice->IsVtuneLogOn())
{ // return directly if ETW log is off
return CM_SUCCESS;
}
CmSafeMemSet(&m_taskProfilingInfo, 0, sizeof(m_taskProfilingInfo));
m_taskProfilingInfo.kernelCount = m_kernelCount;
m_taskProfilingInfo.threadID = CmGetCurThreadId(); // Get Thread ID
MOS_QueryPerformanceCounter((uint64_t*)&m_taskProfilingInfo.enqueueTime.QuadPart); // Get Enqueue Time
m_taskProfilingInfo.kernelNames = MOS_NewArray(char, (CM_MAX_KERNEL_NAME_SIZE_IN_BYTE * m_kernelCount));
CM_CHK_NULL_GOTOFINISH_CMERROR(m_taskProfilingInfo.kernelNames);
m_taskProfilingInfo.localWorkWidth = MOS_NewArray(uint32_t, m_kernelCount);
CM_CHK_NULL_GOTOFINISH_CMERROR(m_taskProfilingInfo.localWorkWidth);
m_taskProfilingInfo.localWorkHeight = MOS_NewArray(uint32_t, m_kernelCount);
CM_CHK_NULL_GOTOFINISH_CMERROR(m_taskProfilingInfo.localWorkHeight);
m_taskProfilingInfo.globalWorkWidth = MOS_NewArray(uint32_t, m_kernelCount);
CM_CHK_NULL_GOTOFINISH_CMERROR(m_taskProfilingInfo.globalWorkWidth);
m_taskProfilingInfo.globalWorkHeight = MOS_NewArray(uint32_t, m_kernelCount);
CM_CHK_NULL_GOTOFINISH_CMERROR(m_taskProfilingInfo.globalWorkHeight);
for (uint32_t i = 0; i < m_kernelCount; i++)
{
CM_CHK_CMSTATUS_GOTOFINISH(GetKernel(i, cmKernel));
CM_CHK_NULL_GOTOFINISH_CMERROR(cmKernel);
//Copy Kernel Name
MOS_SecureStrcpy(m_taskProfilingInfo.kernelNames + m_taskProfilingInfo.kernelNameLen,
CM_MAX_KERNEL_NAME_SIZE_IN_BYTE, cmKernel->GetName());
//Add Kernel Name Length
m_taskProfilingInfo.kernelNameLen += strlen(cmKernel->GetName()) + 1;
CM_CHK_CMSTATUS_GOTOFINISH(cmKernel->GetThreadGroupSpace(perKernelGroupSpace));
if (perTaskThreadGroupSpace)
{ // Per Thread Group Space
perTaskThreadGroupSpace->GetThreadGroupSpaceSize(threadSpaceWidth, threadSpaceHeight,
threadSpaceDepth, threadGroupSpaceWidth,
threadGroupSpaceHeight, threadGroupSpaceDepth);
m_taskProfilingInfo.localWorkWidth[i] = threadSpaceWidth;
m_taskProfilingInfo.localWorkHeight[i] = threadSpaceHeight;
m_taskProfilingInfo.globalWorkWidth[i] = threadSpaceWidth*threadGroupSpaceWidth;
m_taskProfilingInfo.globalWorkHeight[i] = threadSpaceHeight*threadGroupSpaceHeight;
}
else if (perKernelGroupSpace)
{
//Fill each threads group space's info
perKernelGroupSpace->GetThreadGroupSpaceSize(threadSpaceWidth, threadSpaceHeight,
threadSpaceDepth, threadGroupSpaceWidth,
threadGroupSpaceHeight, threadGroupSpaceDepth);
m_taskProfilingInfo.localWorkWidth[i] = threadSpaceWidth;
m_taskProfilingInfo.localWorkHeight[i] = threadSpaceHeight;
m_taskProfilingInfo.globalWorkWidth[i] = threadSpaceWidth*threadGroupSpaceWidth;
m_taskProfilingInfo.globalWorkHeight[i] = threadSpaceHeight*threadGroupSpaceHeight; //Yi need to rethink
}
}
finish:
if (hr != CM_SUCCESS)
{
MosSafeDeleteArray(m_taskProfilingInfo.kernelNames);
MosSafeDeleteArray(m_taskProfilingInfo.localWorkWidth);
MosSafeDeleteArray(m_taskProfilingInfo.localWorkHeight);
MosSafeDeleteArray(m_taskProfilingInfo.globalWorkWidth);
MosSafeDeleteArray(m_taskProfilingInfo.globalWorkHeight);
}
return hr;
}
//*-----------------------------------------------------------------------------
//| Purpose: Release Profiling information
//| Returns: Result of operation.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::VtuneReleaseProfilingInfo()
{
if(!m_cmDevice->IsVtuneLogOn())
{ // return directly if ETW log is off
return CM_SUCCESS;
}
MosSafeDeleteArray(m_taskProfilingInfo.kernelNames);
MosSafeDeleteArray(m_taskProfilingInfo.localWorkWidth);
MosSafeDeleteArray(m_taskProfilingInfo.localWorkHeight);
MosSafeDeleteArray(m_taskProfilingInfo.globalWorkWidth);
MosSafeDeleteArray(m_taskProfilingInfo.globalWorkHeight);
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Reset KernelData status from IN_USE to IDLE.
// It is called immediately after the task being flushed.
//| Returns: Result of operation.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::ResetKernelDataStatus()
{
int32_t hr = CM_SUCCESS;
for(uint32_t krnDataIndex =0 ; krnDataIndex < m_kernelCount; krnDataIndex++ )
{
CmKernelData *kernelData;
CM_CHK_CMSTATUS_GOTOFINISH(GetKernelData(krnDataIndex, kernelData));
CM_CHK_NULL_GOTOFINISH_CMERROR(kernelData);
CM_CHK_CMSTATUS_GOTOFINISH(kernelData->ResetStatus());
}
finish:
return hr;
}
//*-----------------------------------------------------------------------------
//| Purpose: Create thread space data
//| Returns: Result of operation.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::CreateThreadSpaceData(const CmThreadSpaceRT* threadSpace)
{
uint32_t i;
uint32_t width, height;
uint32_t *kernelCoordinateIndex = nullptr;
int hr = CM_SUCCESS;
CmThreadSpaceRT *threadSpaceRT = const_cast<CmThreadSpaceRT*>(threadSpace);
CmKernelRT* kernelInThreadSpace = nullptr;
CmKernelRT* kernelInTask = nullptr;
CM_CHK_NULL_GOTOFINISH(threadSpaceRT, CM_NULL_POINTER);
threadSpaceRT->GetThreadSpaceSize(m_threadSpaceWidth, m_threadSpaceHeight);
if (threadSpaceRT->IsThreadAssociated())
{
m_threadCoordinates = MOS_NewArray(PCM_HAL_SCOREBOARD, m_kernelCount);
CM_CHK_NULL_GOTOFINISH(m_threadCoordinates, CM_FAILURE);
CmSafeMemSet(m_threadCoordinates, 0, m_kernelCount*sizeof(PCM_HAL_SCOREBOARD));
m_dependencyMasks = MOS_NewArray(PCM_HAL_MASK_AND_RESET, m_kernelCount);
CM_CHK_NULL_GOTOFINISH(m_dependencyMasks, CM_FAILURE);
CmSafeMemSet(m_dependencyMasks, 0, m_kernelCount*sizeof(PCM_HAL_MASK_AND_RESET));
kernelCoordinateIndex = MOS_NewArray(uint32_t, m_kernelCount);
if(m_threadCoordinates && kernelCoordinateIndex && m_dependencyMasks)
{
CmSafeMemSet(kernelCoordinateIndex, 0, m_kernelCount*sizeof(uint32_t));
for (i = 0; i< m_kernelCount; i++)
{
kernelCoordinateIndex[i] = 0;
uint32_t threadCount;
this->GetKernel(i, kernelInTask);
if(kernelInTask == nullptr)
{
CM_ASSERTMESSAGE("Error: Invalid kernel pointer in task.");
hr = CM_NULL_POINTER;
goto finish;
}
kernelInTask->GetThreadCount(threadCount);
if (threadCount == 0)
{
threadCount = m_threadSpaceWidth*m_threadSpaceHeight;
}
m_threadCoordinates[i] = MOS_NewArray(CM_HAL_SCOREBOARD, threadCount);
if (m_threadCoordinates[i])
{
CmSafeMemSet(m_threadCoordinates[i], 0, sizeof(CM_HAL_SCOREBOARD)* threadCount);
}
else
{
CM_ASSERTMESSAGE("Error: Pointer to thread coordinates is null.");
hr = CM_NULL_POINTER;
goto finish;
}
m_dependencyMasks[i] = MOS_NewArray(CM_HAL_MASK_AND_RESET, threadCount);
if( m_dependencyMasks[i] )
{
CmSafeMemSet(m_dependencyMasks[i], 0, sizeof(CM_HAL_MASK_AND_RESET) * threadCount);
}
else
{
CM_ASSERTMESSAGE("Error: Pointer to dependency masks is null.");
hr = CM_NULL_POINTER;
goto finish;
}
}
CM_THREAD_SPACE_UNIT *threadSpaceUnit = nullptr;
threadSpaceRT->GetThreadSpaceSize(width, height);
threadSpaceRT->GetThreadSpaceUnit(threadSpaceUnit);
uint32_t *boardOrder = nullptr;
threadSpaceRT->GetBoardOrder(boardOrder);
for (uint32_t tIndex=0; tIndex < height*width; tIndex ++)
{
kernelInThreadSpace = static_cast<CmKernelRT *>(threadSpaceUnit[boardOrder[tIndex]].kernel);
if (kernelInThreadSpace == nullptr)
{
if (threadSpaceRT->GetNeedSetKernelPointer())
{
kernelInThreadSpace = threadSpaceRT->GetKernelPointer();
}
if (kernelInThreadSpace == nullptr)
{
CM_ASSERTMESSAGE("Error: Invalid kernel pointer in task.");
hr = CM_NULL_POINTER;
goto finish;
}
}
uint32_t kIndex = kernelInThreadSpace->GetIndexInTask();
m_threadCoordinates[kIndex][kernelCoordinateIndex[kIndex]].x
= threadSpaceUnit[boardOrder[tIndex]].scoreboardCoordinates.x;
m_threadCoordinates[kIndex][kernelCoordinateIndex[kIndex]].y
= threadSpaceUnit[boardOrder[tIndex]].scoreboardCoordinates.y;
m_threadCoordinates[kIndex][kernelCoordinateIndex[kIndex]].mask
= threadSpaceUnit[boardOrder[tIndex]].dependencyMask;
m_threadCoordinates[kIndex][kernelCoordinateIndex[kIndex]].resetMask
= threadSpaceUnit[boardOrder[tIndex]].reset;
m_threadCoordinates[kIndex][kernelCoordinateIndex[kIndex]].color
= threadSpaceUnit[boardOrder[tIndex]].scoreboardColor;
m_threadCoordinates[kIndex][kernelCoordinateIndex[kIndex]].sliceSelect
= threadSpaceUnit[boardOrder[tIndex]].sliceDestinationSelect;
m_threadCoordinates[kIndex][kernelCoordinateIndex[kIndex]].subSliceSelect
= threadSpaceUnit[boardOrder[tIndex]].subSliceDestinationSelect;
m_dependencyMasks[kIndex][kernelCoordinateIndex[kIndex]].mask
= threadSpaceUnit[boardOrder[tIndex]].dependencyMask;
m_dependencyMasks[kIndex][kernelCoordinateIndex[kIndex]].resetMask
= threadSpaceUnit[boardOrder[tIndex]].reset;
kernelCoordinateIndex[kIndex] ++;
}
MosSafeDeleteArray(kernelCoordinateIndex);
}
else
{
CM_ASSERTMESSAGE("Error: Failed to create thread space data.");
hr = CM_FAILURE;
goto finish;
}
m_isThreadCoordinatesExisted = true;
}
else
{
m_threadCoordinates = nullptr;
m_dependencyMasks = nullptr;
m_isThreadCoordinatesExisted = false;
}
if (threadSpaceRT->IsDependencySet())
{
threadSpaceRT->GetDependencyPatternType(m_dependencyPattern);
}
threadSpaceRT->GetColorCountMinusOne(m_colorCountMinusOne);
threadSpaceRT->GetMediaWalkerGroupSelect(m_mediaWalkerGroupSelect);
threadSpaceRT->GetWalkingPattern(m_walkingPattern);
m_mediaWalkerParamsSet = threadSpaceRT->CheckWalkingParametersSet();
if( m_mediaWalkerParamsSet )
{
CM_WALKING_PARAMETERS tmpMWParams;
CM_CHK_CMSTATUS_GOTOFINISH(threadSpaceRT->GetWalkingParameters(tmpMWParams));
CmSafeMemCopy(&m_walkingParameters, &tmpMWParams, sizeof(tmpMWParams));
}
m_dependencyVectorsSet = threadSpaceRT->CheckDependencyVectorsSet();
if( m_dependencyVectorsSet )
{
CM_HAL_DEPENDENCY tmpDepVectors;
CM_CHK_CMSTATUS_GOTOFINISH(threadSpaceRT->GetDependencyVectors(tmpDepVectors));
CmSafeMemCopy(&m_dependencyVectors, &tmpDepVectors, sizeof(tmpDepVectors));
}
finish:
if(hr != CM_SUCCESS)
{
if(m_threadCoordinates )
{
for (i = 0; i< m_kernelCount; i++)
{
MosSafeDeleteArray(m_threadCoordinates[i]);
}
}
if(m_dependencyMasks)
{
for (i = 0; i< m_kernelCount; i++)
{
MosSafeDeleteArray(m_dependencyMasks[i]);
}
}
MosSafeDeleteArray(m_threadCoordinates);
MosSafeDeleteArray(m_dependencyMasks);
MosSafeDeleteArray(kernelCoordinateIndex);
}
return hr;
}
//*-----------------------------------------------------------------------------
//| Purpose: Get thread space's coordinates
//| Returns: CM_SUCCESS.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetKernelCoordinates(const uint32_t index, void *&kernelCoordinates)
{
if (m_threadCoordinates != nullptr)
{
kernelCoordinates = (void *)m_threadCoordinates[index];
}
else
{
kernelCoordinates = nullptr;
}
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Get thread space's dependency masks
//| Returns: CM_SUCCESS.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetKernelDependencyMasks(const uint32_t index, void *&kernelDependencyMasks)
{
if (m_dependencyMasks != nullptr)
{
kernelDependencyMasks = (void *)m_dependencyMasks[index];
}
else
{
kernelDependencyMasks = nullptr;
}
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Get dependency pattern
//| Returns: CM_SUCCESS.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetDependencyPattern(CM_DEPENDENCY_PATTERN &dependencyPattern)
{
dependencyPattern = m_dependencyPattern;
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Get media walking pattern
//| Returns: CM_SUCCESS.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetWalkingPattern(CM_WALKING_PATTERN &walkingPattern)
{
walkingPattern = m_walkingPattern;
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Get media walking parameters
//| Returns: CM_FAILURE if dest ptr is nullptr, CM_SUCCESS otherwise
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetWalkingParameters(CM_WALKING_PARAMETERS &walkingParameters)
{
CmSafeMemCopy(&walkingParameters, &m_walkingParameters, sizeof(m_walkingParameters));
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Check to see if media walking parameters have been set
//| Returns: true if media walking parameters set, false otherwise
//*-----------------------------------------------------------------------------
bool CmTaskInternal::CheckWalkingParametersSet( )
{
return m_mediaWalkerParamsSet;
}
//*-----------------------------------------------------------------------------
//| Purpose: Get dependency vectors
//| Returns: CM_FAILURE if dest ptr is nullptr, CM_SUCCESS otherwise
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetDependencyVectors(CM_HAL_DEPENDENCY &dependencyVectors)
{
CmSafeMemCopy(&dependencyVectors, &m_dependencyVectors, sizeof(m_dependencyVectors));
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Check to see if dependency vectors have been set
//| Returns: true if dependency vectors are set, false otherwise
//*-----------------------------------------------------------------------------
bool CmTaskInternal::CheckDependencyVectorsSet( )
{
return m_dependencyVectorsSet;
}
//*-----------------------------------------------------------------------------
//| Purpose: Get the total thread count
//| Returns: CM_SUCCESS.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetTotalThreadCount( uint32_t& totalThreadCount )
{
totalThreadCount = m_totalThreadCount;
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Get the width,height of thread space
//| Returns: CM_SUCCESS.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetThreadSpaceSize(uint32_t& width, uint32_t& height )
{
width = m_threadSpaceWidth;
height = m_threadSpaceHeight;
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Get the color count minus one of the thread space
//| Used to dispatch multiple sets of dependency threads
//| for media walker
//| Returns: CM_SUCCESS.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetColorCountMinusOne( uint32_t& colorCount )
{
colorCount = m_colorCountMinusOne;
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Whether thread space is created
//| Returns: Boolean.
//*-----------------------------------------------------------------------------
bool CmTaskInternal::IsThreadSpaceCreated(void )
{
return m_isThreadSpaceCreated;
}
//*-----------------------------------------------------------------------------
//| Purpose: Whether thread coordinates are existed
//| Returns: Boolean.
//*-----------------------------------------------------------------------------
bool CmTaskInternal::IsThreadCoordinatesExisted(void)
{
return m_isThreadCoordinatesExisted;
}
//*-----------------------------------------------------------------------------
//| Purpose: Whether thread coordinates are existed
//| Returns: Result of operation.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetThreadGroupSpaceSize(uint32_t& threadSpaceWidth, uint32_t& threadSpaceHeight,
uint32_t& threadSpaceDepth, uint32_t& groupSpaceWidth,
uint32_t& groupSpaceHeight, uint32_t& groupSpaceDepth)
{
threadSpaceWidth = m_threadSpaceWidth;
threadSpaceHeight = m_threadSpaceHeight;
threadSpaceDepth = m_threadSpaceDepth;
groupSpaceWidth = m_groupSpaceWidth;
groupSpaceHeight = m_groupSpaceHeight;
groupSpaceDepth = m_groupSpaceDepth;
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Get the size of sharedlocalmemory
//| Returns: CM_SUCCESS.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetSLMSize(uint32_t& slmSize)
{
slmSize = m_slmSize;
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Get the size of spill memory used
//| Returns: CM_SUCCESS.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetSpillMemUsed(uint32_t& spillMemUsed)
{
spillMemUsed = m_spillMemUsed;
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Get the hints for EnqueueWithHints
//| Returns: CM_SUCCESS.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetHints(uint32_t& hints)
{
hints = m_hints;
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Gets the number of tasks generated for EnqueueWithHints
//| Used when splitting large task to smaller tasks
//| Returns: CM_SUCCESS.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetNumTasksGenerated(uint32_t& numTasksGenerated)
{
numTasksGenerated = m_numTasksGenerated;
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Gets whether or not this task is the last task for EnqueueWithHints
//| Used to identify last smaller task when splitting large task
//| Returns: CM_SUCCESS.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetLastTask(bool& isLastTask)
{
isLastTask = m_isLastTask;
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Whether thread group space is created
//| Returns: Value.
//*-----------------------------------------------------------------------------
bool CmTaskInternal::IsThreadGroupSpaceCreated(void)
{
return m_isThreadGroupSpaceCreated;
}
//*-----------------------------------------------------------------------------
//| Purpose: Allocate Space to record kernel surface's information
//| Returns: result of operation.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::AllocateKernelSurfInfo()
{
//Allocate Surf info array
m_kernelSurfInfo.kernelNum = m_kernelCount;
m_kernelSurfInfo.surfEntryInfosArray
= (CM_HAL_SURFACE_ENTRY_INFO_ARRAY*)MOS_AllocAndZeroMemory(m_kernelCount *
sizeof(CM_HAL_SURFACE_ENTRY_INFO_ARRAY));
if(m_kernelSurfInfo.surfEntryInfosArray == nullptr)
{
CM_ASSERTMESSAGE("Error: Mem allocation fail.");
return CM_OUT_OF_HOST_MEMORY;
}
for( uint32_t i = 0; i < m_kernelCount; i ++ )
{
CmKernelRT * tempCmKernel = nullptr;
this->GetKernel(i, tempCmKernel);
if(tempCmKernel == nullptr)
{
CM_ASSERTMESSAGE("Error: Invalid kernel pointer.");
return CM_FAILURE;
}
CM_ARG* arg=NULL;
tempCmKernel->GetArgs( arg );
uint32_t argCount = 0;
tempCmKernel->GetArgCount( argCount);
//allocate memory for non_static buffer&2D&3D
uint32_t surfEntryNum = 0;
for( uint32_t j = 0; j < argCount; j ++ )
{
switch(arg[ j ].unitKind)
{
case ARG_KIND_SURFACE_1D:
surfEntryNum = surfEntryNum + arg[ j ].unitCount * arg[j].unitSize/sizeof(int);
break;
case ARG_KIND_SURFACE_2D:
case ARG_KIND_SURFACE_2D_UP:
case ARG_KIND_SURFACE_3D:
case ARG_KIND_SURFACE_SAMPLER8X8_AVS:
case ARG_KIND_SURFACE_SAMPLER8X8_VA:
surfEntryNum = surfEntryNum + 3 * arg[ j ].unitCount * arg[j].unitSize/sizeof(int);//one 2D or 3D can have upto 3 planes
break;
case ARG_KIND_SURFACE_VME:
surfEntryNum = surfEntryNum + 24 * arg[ j ].unitCount;//surfaceVME will use upto 8 surfaces, each one can have upto 3 planes
break;
default:
break;
}
}
CM_HAL_SURFACE_ENTRY_INFO_ARRAY* tempArray = m_kernelSurfInfo.surfEntryInfosArray;
if(surfEntryNum>0)
{
tempArray[i].maxEntryNum = surfEntryNum;
tempArray[i].surfEntryInfos = (CM_SURFACE_DETAILS*)MOS_AllocAndZeroMemory(surfEntryNum*sizeof(CM_SURFACE_DETAILS));
if(tempArray[i].surfEntryInfos == nullptr)
{
CM_ASSERTMESSAGE("Error: Mem allocation fail.");
return CM_OUT_OF_HOST_MEMORY;
}
}
//allocate memory for those 7 static buffers
uint32_t globalBufNum=CM_GLOBAL_SURFACE_NUMBER + CM_GTPIN_BUFFER_NUM;
tempArray[i].globalSurfNum=globalBufNum;
tempArray[i].globalSurfInfos = (CM_SURFACE_DETAILS*)MOS_AllocAndZeroMemory(
globalBufNum*sizeof(CM_SURFACE_DETAILS));
if(tempArray[i].globalSurfInfos == nullptr)
{
CM_ASSERTMESSAGE("Mem allocation fail.");
return CM_OUT_OF_HOST_MEMORY;
}
}
return CM_SUCCESS;
}
int32_t CmTaskInternal::GetKernelSurfInfo(CM_HAL_SURFACE_ENTRY_INFO_ARRAYS & surfEntryInfoArray)
{
surfEntryInfoArray = m_kernelSurfInfo;
return CM_SUCCESS;
}
int32_t CmTaskInternal::ClearKernelSurfInfo()
{
if (m_kernelSurfInfo.surfEntryInfosArray == nullptr)
{ // if surfEntryInfosArray is empty, return directly
return CM_SUCCESS;
}
//free memory
for( uint32_t i = 0; i < m_kernelCount; i ++ )
{
if (m_kernelSurfInfo.surfEntryInfosArray[i].surfEntryInfos != nullptr)
{
MosSafeDelete(m_kernelSurfInfo.surfEntryInfosArray[i].surfEntryInfos);
}
if (m_kernelSurfInfo.surfEntryInfosArray[i].globalSurfInfos!= nullptr)
{
MosSafeDelete(m_kernelSurfInfo.surfEntryInfosArray[i].globalSurfInfos);
}
}
MosSafeDelete(m_kernelSurfInfo.surfEntryInfosArray);
m_kernelSurfInfo.kernelNum = 0 ;
m_kernelSurfInfo.surfEntryInfosArray = nullptr;
return CM_SUCCESS;
}
int32_t CmTaskInternal::GetTaskType(uint32_t& taskType)
{
taskType = m_taskType;
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Get vebox state
//| Returns: Result of operation.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::GetVeboxState(CM_VEBOX_STATE &veboxState)
{
veboxState = m_veboxState;
return CM_SUCCESS;
}
int32_t CmTaskInternal::GetVeboxParam(CmBufferUP * &veboxParam)
{
veboxParam = m_veboxParam;
return CM_SUCCESS;
}
int32_t CmTaskInternal::GetVeboxSurfaceData(CM_VEBOX_SURFACE_DATA &veboxSurfaceData)
{
veboxSurfaceData = m_veboxSurfaceData;
return CM_SUCCESS;
}
uint64_t CmTaskInternal::GetSyncBitmap()
{
return m_ui64SyncBitmap;
}
uint64_t CmTaskInternal::GetConditionalEndBitmap()
{
return m_ui64ConditionalEndBitmap;
}
CM_HAL_CONDITIONAL_BB_END_INFO* CmTaskInternal::GetConditionalEndInfo()
{
return m_conditionalEndInfo;
}
//*-----------------------------------------------------------------------------
//| Purpose: Set power option for this task
//| Returns: Result of operation.
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::SetPowerOption( PCM_POWER_OPTION powerOption )
{
if (powerOption == nullptr)
{
CM_ASSERTMESSAGE("Error: Pointer to power option is null.");
return CM_NULL_POINTER;
}
CmSafeMemCopy( &m_powerOption, powerOption, sizeof( m_powerOption ) );
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Get power option for this task
//| Returns: Pointer to power option.
//*-----------------------------------------------------------------------------
PCM_POWER_OPTION CmTaskInternal::GetPowerOption()
{
return &m_powerOption;
}
#if _DEBUG
const char *gDependencyPatternString[] =
{
"DEPENDENCY_NONE",
"DEPENDENCY_WAVEFRONT45",
"DEPENDENCY_WAVEFRONT26"
};
//Only for debugging
int32_t CmTaskInternal::DisplayThreadSpaceData(uint32_t width, uint32_t height)
{
if (m_threadCoordinates != nullptr)
{
CM_NORMALMESSAGE("Score board[Kernel x: (x1, y1), (x2, y2)...]:");
for (uint32_t i = 0; i < m_kernelCount; i ++)
{
CmKernelRT *kernelRT = nullptr;
GetKernel(i, kernelRT);
if(nullptr == kernelRT)
{
return CM_FAILURE;
}
uint32_t threadCount;
kernelRT->GetThreadCount(threadCount);
if (threadCount == 0)
{
threadCount = m_threadSpaceWidth*m_threadSpaceHeight;
}
CM_NORMALMESSAGE("Kernel %d: ", i);
for (uint32_t j=0; j<threadCount; j++)
{
CM_NORMALMESSAGE("(%d, %d) ", m_threadCoordinates[i][j].x, m_threadCoordinates[i][j].y);
}
}
}
else
{
CM_NORMALMESSAGE("Score Board is NULL.");
}
if (m_dependencyPattern <= CM_WAVEFRONT26)
{
CM_NORMALMESSAGE("Dependency Pattern: %s.", gDependencyPatternString[m_dependencyPattern]);
}
else
{
CM_NORMALMESSAGE("Dependency Pattern: UNASSIGNED.");
}
return CM_SUCCESS;
}
#endif
int32_t CmTaskInternal::GetMediaWalkerGroupSelect(CM_MW_GROUP_SELECT& groupSelect)
{
groupSelect = m_mediaWalkerGroupSelect;
return CM_SUCCESS;
}
//*-----------------------------------------------------------------------------
//| Purpose: Update surface state on task destroy stage
//*-----------------------------------------------------------------------------
int32_t CmTaskInternal::UpdateSurfaceStateOnTaskCreation()
{
CmSurfaceManager* surfaceMgr = nullptr;
int32_t *surfState = nullptr;
m_cmDevice->GetSurfaceManager(surfaceMgr);
if (surfaceMgr == nullptr)
{
CM_ASSERTMESSAGE("Error: Pointer to surface manager is null.");
return CM_NULL_POINTER;
}
uint32_t poolSize = surfaceMgr->GetSurfacePoolSize();
uint32_t handle = 0;
uint32_t curTaskSurfCnt = 0;
void ** curTaskSurfResArray = nullptr;
uint32_t refSurfCnt = 0;
uint32_t *refSurfHandleArray = nullptr;
CM_RETURN_CODE hr = CM_SUCCESS;
curTaskSurfResArray = (void **)MOS_AllocAndZeroMemory(sizeof(void *)*poolSize);
CM_CHK_NULL_RETURN_CMERROR(curTaskSurfResArray);
CSync* surfaceLock = m_cmDevice->GetSurfaceCreationLock();
if (surfaceLock == nullptr)
{
CM_ASSERTMESSAGE("Error: Pointer to surface creation lock is null.");
if (curTaskSurfResArray)
{
MOS_FreeMemory(curTaskSurfResArray);
curTaskSurfResArray = nullptr;
}
return CM_NULL_POINTER;
}
surfaceLock->Acquire();
// get the last tracker
PCM_CONTEXT_DATA cmData = ( PCM_CONTEXT_DATA )m_cmDevice->GetAccelData();
PCM_HAL_STATE state = nullptr;
CM_CHK_NULL_GOTOFINISH_CMERROR(cmData);
state = cmData->cmHalState;
CM_CHK_NULL_GOTOFINISH_CMERROR(state);
if (!m_isSurfaceUpdateDone)
{
for (uint32_t i = 0; i < poolSize; i++)
{
if (m_surfaceArray[i])
{
CmSurface *surface = NULL;
CM_CHK_CMSTATUS_GOTOFINISH(surfaceMgr->GetSurface(i, surface));
if (surface == nullptr) // surface destroyed but not updated in kernel
{
continue;
}
if (m_taskType == CM_INTERNAL_TASK_VEBOX)
{
surface->SetVeboxTracker(state->renderHal->veBoxTrackerRes.currentTrackerId);
}
else
{
surface->SetRenderTracker(state->renderHal->currentTrackerIndex,
state->renderHal->trackerProducer.GetNextTracker(state->renderHal->currentTrackerIndex));
}
// Push this surface's resource into array for CP check.
switch (surface->Type())
{
case CM_ENUM_CLASS_TYPE_CMBUFFER_RT :
static_cast< CmBuffer_RT* >( surface )->GetHandle(handle);
curTaskSurfResArray[curTaskSurfCnt++] = (void *)&state->bufferTable[handle].osResource;
break;
case CM_ENUM_CLASS_TYPE_CMSURFACE2D :
static_cast< CmSurface2DRT* >( surface )->GetHandle(handle);
curTaskSurfResArray[curTaskSurfCnt++] = (void *)&state->umdSurf2DTable[handle].osResource;
break;
case CM_ENUM_CLASS_TYPE_CMSURFACE2DUP:
static_cast< CmSurface2DUPRT* >( surface )->GetHandle(handle);
curTaskSurfResArray[curTaskSurfCnt++] = (void *)&state->surf2DUPTable[handle].osResource;
break;
case CM_ENUM_CLASS_TYPE_CMSURFACE3D :
static_cast< CmSurface3DRT* >( surface )->GetHandle(handle);
curTaskSurfResArray[curTaskSurfCnt++] = (void *)&state->surf3DTable[handle].osResource;
break;
case CM_ENUM_CLASS_TYPE_CMSURFACEVME:
static_cast< CmSurfaceVme* >( surface )->GetIndexCurrent(handle);
curTaskSurfResArray[curTaskSurfCnt++] = (void *)&state->umdSurf2DTable[handle].osResource; // current surface
static_cast< CmSurfaceVme* >( surface )->GetIndexForwardCount(refSurfCnt);
static_cast< CmSurfaceVme* >( surface )->GetIndexForwardArray(refSurfHandleArray);
for(i = 0; i < refSurfCnt; i++)
{
curTaskSurfResArray[curTaskSurfCnt++] = (void *)&state->umdSurf2DTable[refSurfHandleArray[i]].osResource; // forward surfaces
}
static_cast< CmSurfaceVme* >( surface )->GetIndexForwardCount(refSurfCnt);
static_cast< CmSurfaceVme* >( surface )->GetIndexForwardArray(refSurfHandleArray);
for(i = 0; i < refSurfCnt; i++)
{
curTaskSurfResArray[curTaskSurfCnt++] = (void *)&state->umdSurf2DTable[refSurfHandleArray[i]].osResource; // backward surfaces
}
break;
case CM_ENUM_CLASS_TYPE_CMSURFACESAMPLER8X8:
static_cast< CmSurfaceSampler8x8* >( surface )->GetIndexCurrent(handle);
curTaskSurfResArray[curTaskSurfCnt++] = (void *)&state->umdSurf2DTable[handle].osResource;
break;
case CM_ENUM_CLASS_TYPE_CMSURFACESAMPLER:
static_cast< CmSurfaceSampler* >( surface )->GetHandle(handle);
SAMPLER_SURFACE_TYPE type;
static_cast< CmSurfaceSampler* >( surface )->GetSurfaceType(type);
if (type == SAMPLER_SURFACE_TYPE_2D)
{
curTaskSurfResArray[curTaskSurfCnt++] = (void *)&state->umdSurf2DTable[handle].osResource;
}
else if (type == SAMPLER_SURFACE_TYPE_2DUP)
{
curTaskSurfResArray[curTaskSurfCnt++] = (void *)&state->surf2DUPTable[handle].osResource;
}
else if (type == SAMPLER_SURFACE_TYPE_3D)
{
curTaskSurfResArray[curTaskSurfCnt++] = (void *)&state->surf3DTable[handle].osResource;
}
else
{
hr = CM_INVALID_ARG_INDEX;
goto finish;
}
break;
default:
break;
}
}
}
m_isSurfaceUpdateDone = true;
}
// Check if there is any secure surface.
if (curTaskSurfCnt > 0 && state->osInterface && state->osInterface->osCpInterface)
{
state->osInterface->osCpInterface->PrepareResources(curTaskSurfResArray, curTaskSurfCnt, nullptr, 0);
}
finish:
surfaceLock->Release();
if (curTaskSurfResArray)
{
MOS_FreeMemory(curTaskSurfResArray);
curTaskSurfResArray = nullptr;
}
return hr;
}
#if CM_LOG_ON
std::string CmTaskInternal::Log()
{
std::ostringstream oss;
oss << "Enqueue Task Type:" << m_taskType
<< " Kernel Count:" << m_kernelCount
<< " Total Thread Count:" << m_totalThreadCount
<< " Sync Bit:"<<m_ui64SyncBitmap
<< " Conditional End Bit:" << m_ui64ConditionalEndBitmap
<< std::endl;
switch(m_taskType)
{
case CM_INTERNAL_TASK_WITH_THREADSPACE:
if ( m_isThreadSpaceCreated )
{
oss << "Thread Space Width :" << m_threadSpaceWidth << " Height :" << m_threadSpaceHeight
<< "Walker Patten :" << (int)m_walkingPattern << std::endl;
}
break;
case CM_INTERNAL_TASK_WITH_THREADGROUPSPACE:
if(m_isThreadGroupSpaceCreated)
{
oss << "Thread Group Space Width:" << m_groupSpaceWidth << " Height:" << m_groupSpaceHeight
<< "SLM Size:" <<m_slmSize << std::endl;
}
break;
case CM_INTERNAL_TASK_VEBOX:
break;
case CM_INTERNAL_TASK_ENQUEUEWITHHINTS:
oss << " Hints :" << m_hints
<< " Thread Space Width :" << m_threadSpaceWidth
<< " Height :" << m_threadSpaceHeight
<< " Walker Patten :" << (int)m_walkingPattern
<< std::endl;
break;
default: // by default, assume the task is considered as general task: CM_INTERNAL_TASK_WITH_THREADSPACE
break;
}
for (uint32_t i=0 ; i< m_kernelCount; i++)
{
CmKernelRT* kernel = (CmKernelRT*)m_kernels.GetElement( i );
oss << kernel->Log(); // log each kernel
}
return oss.str();
}
CM_HAL_STATE* CmTaskInternal::GetHalState() { return m_cmDevice->GetHalState(); }
#endif // #if CM_LOG_ON
void CmTaskInternal::SurfaceDump(int32_t taskId)
{
#if MDF_SURFACE_CONTENT_DUMP
for (uint32_t i=0 ; i< m_kernelCount; i++)
{
CmKernelRT* kernel = (CmKernelRT*)m_kernels.GetElement( i );
kernel->SurfaceDump(i, taskId);
}
#endif
}
int32_t CmTaskInternal::SetProperty(CM_TASK_CONFIG * taskConfig)
{
if (taskConfig == nullptr)
{
CM_ASSERTMESSAGE("Error: Pointer to task config is null.");
return CM_NULL_POINTER;
}
CmSafeMemCopy(&m_taskConfig, taskConfig, sizeof(m_taskConfig));
return CM_SUCCESS;
}
int32_t CmTaskInternal::GetProperty(CM_TASK_CONFIG &taskConfig)
{
taskConfig = m_taskConfig;
return CM_SUCCESS;
}
void *CMRT_UMD::CmTaskInternal::GetMediaStatePtr()
{
return m_mediaStatePtr;
}
} // namespace