blob: 6ae75ce04d4e90d5d43bcb0f8b69893db82c7bca [file] [log] [blame]
/*
* Copyright (c) 2020-2021, 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 media_render_cmd_packet.cpp
//! \brief Defines the interface for media render workload cmd packet
//! \details The media cmd packet is dedicated for command buffer sequenece submit
//!
#include "media_render_cmd_packet.h"
#include "mos_oca_interface.h"
#include "renderhal_platform_interface.h"
#define COMPUTE_WALKER_THREAD_SPACE_WIDTH 1
#define COMPUTE_WALKER_THREAD_SPACE_HEIGHT 1
#define COMPUTE_WALKER_THREAD_SPACE_DEPTH 1
RenderCmdPacket::RenderCmdPacket(MediaTask* task, PMOS_INTERFACE pOsinterface, RENDERHAL_INTERFACE *renderHal) : CmdPacket(task),
m_renderHal(renderHal),
m_cpInterface(nullptr),
m_osInterface(pOsinterface)
{
Init();
}
RenderCmdPacket::~RenderCmdPacket()
{
Destroy();
}
MOS_STATUS RenderCmdPacket::Init()
{
if (!m_renderHal)
{
m_renderHal = (PRENDERHAL_INTERFACE)MOS_AllocAndZeroMemory(sizeof(RENDERHAL_INTERFACE));
RENDER_PACKET_CHK_NULL_RETURN(m_renderHal);
RENDER_PACKET_CHK_STATUS_RETURN(RenderHal_InitInterface(
m_renderHal,
&m_cpInterface,
m_osInterface));
RENDERHAL_SETTINGS RenderHalSettings;
RenderHalSettings.iMediaStates = 32; // Init MEdia state values
RENDER_PACKET_CHK_STATUS_RETURN(m_renderHal->pfnInitialize(m_renderHal, &RenderHalSettings));
}
else
{
RENDER_PACKET_NORMALMESSAGE("RenderHal Already been created");
}
bool mediaWalkerUsed = false;
bool computeWalkerUsed = false;
mediaWalkerUsed = m_renderHal->pfnGetMediaWalkerStatus(m_renderHal) ? true : false;
computeWalkerUsed = m_renderHal->pRenderHalPltInterface->IsComputeContextInUse(m_renderHal);
if (mediaWalkerUsed && !computeWalkerUsed)
{
m_walkerType = WALKER_TYPE_MEDIA;
}
else if (computeWalkerUsed)
{
m_walkerType = WALKER_TYPE_COMPUTE;
}
else
{
m_walkerType = WALKER_TYPE_DISABLED;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS RenderCmdPacket::Destroy()
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
return MOS_STATUS_SUCCESS;
}
MOS_STATUS RenderCmdPacket::Submit(MOS_COMMAND_BUFFER* commandBuffer, uint8_t packetPhase)
{
PMOS_INTERFACE pOsInterface = nullptr;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
uint32_t dwSyncTag = 0;
int32_t i = 0, iRemaining = 0;
PMHW_MI_INTERFACE pMhwMiInterface = nullptr;
MhwRenderInterface* pMhwRender = nullptr;
MHW_MEDIA_STATE_FLUSH_PARAM FlushParam = {};
bool bEnableSLM = false;
RENDERHAL_GENERIC_PROLOG_PARAMS GenericPrologParams = {};
MOS_RESOURCE GpuStatusBuffer = {};
MediaPerfProfiler* pPerfProfiler = nullptr;
MOS_CONTEXT* pOsContext = nullptr;
PMHW_MI_MMIOREGISTERS pMmioRegisters = nullptr;
RENDER_PACKET_CHK_NULL_RETURN(m_renderHal);
RENDER_PACKET_CHK_NULL_RETURN(m_renderHal->pMhwRenderInterface);
RENDER_PACKET_CHK_NULL_RETURN(m_renderHal->pMhwMiInterface);
RENDER_PACKET_CHK_NULL_RETURN(m_renderHal->pMhwRenderInterface->GetMmioRegisters());
RENDER_PACKET_CHK_NULL_RETURN(m_renderHal->pOsInterface);
RENDER_PACKET_CHK_NULL_RETURN(m_renderHal->pOsInterface->pOsContext);
eStatus = MOS_STATUS_UNKNOWN;
pOsInterface = m_renderHal->pOsInterface;
pMhwMiInterface = m_renderHal->pMhwMiInterface;
pMhwRender = m_renderHal->pMhwRenderInterface;
iRemaining = 0;
FlushParam = g_cRenderHal_InitMediaStateFlushParams;
pPerfProfiler = m_renderHal->pPerfProfiler;
pOsContext = pOsInterface->pOsContext;
pMmioRegisters = pMhwRender->GetMmioRegisters();
RENDER_PACKET_CHK_STATUS_RETURN(SetPowerMode(CombinedFc));
// Initialize command buffer and insert prolog
RENDER_PACKET_CHK_STATUS_RETURN(m_renderHal->pfnInitCommandBuffer(m_renderHal, commandBuffer, &GenericPrologParams));
RENDER_PACKET_CHK_STATUS_RETURN(pPerfProfiler->AddPerfCollectStartCmd((void*)m_renderHal, pOsInterface, pMhwMiInterface, commandBuffer));
RENDER_PACKET_CHK_STATUS_RETURN(NullHW::StartPredicate(pMhwMiInterface, commandBuffer));
// Write timing data for 3P budget
RENDER_PACKET_CHK_STATUS_RETURN(m_renderHal->pfnSendTimingData(m_renderHal, commandBuffer, true));
bEnableSLM = false; // Media walker first
RENDER_PACKET_CHK_STATUS_RETURN(m_renderHal->pfnSetCacheOverrideParams(
m_renderHal,
&m_renderHal->L3CacheSettings,
bEnableSLM));
// Flush media states
RENDER_PACKET_CHK_STATUS_RETURN(m_renderHal->pfnSendMediaStates(
m_renderHal,
commandBuffer,
(m_walkerType == WALKER_TYPE_MEDIA) ? &m_mediaWalkerParams : nullptr,
&m_gpgpuWalkerParams));
// Write back GPU Status tag
if (!pOsInterface->bEnableKmdMediaFrameTracking)
{
RENDER_PACKET_CHK_STATUS_RETURN(m_renderHal->pfnSendRcsStatusTag(m_renderHal, commandBuffer));
}
RENDER_PACKET_CHK_STATUS_RETURN(NullHW::StopPredicate(pMhwMiInterface, commandBuffer));
RENDER_PACKET_CHK_STATUS_RETURN(pPerfProfiler->AddPerfCollectEndCmd((void*)m_renderHal, pOsInterface, pMhwMiInterface, commandBuffer));
// Write timing data for 3P budget
RENDER_PACKET_CHK_STATUS_RETURN(m_renderHal->pfnSendTimingData(m_renderHal, commandBuffer, false));
MHW_PIPE_CONTROL_PARAMS PipeControlParams;
MOS_ZeroMemory(&PipeControlParams, sizeof(PipeControlParams));
PipeControlParams.dwFlushMode = MHW_FLUSH_WRITE_CACHE;
PipeControlParams.bGenericMediaStateClear = true;
PipeControlParams.bIndirectStatePointersDisable = true;
PipeControlParams.bDisableCSStall = false;
RENDER_PACKET_CHK_STATUS_RETURN(pMhwMiInterface->AddPipeControl(commandBuffer, nullptr, &PipeControlParams));
if (MEDIA_IS_WA(m_renderHal->pWaTable, WaSendDummyVFEafterPipelineSelect))
{
MHW_VFE_PARAMS VfeStateParams = {};
VfeStateParams.dwNumberofURBEntries = 1;
RENDER_PACKET_CHK_STATUS_RETURN(pMhwRender->AddMediaVfeCmd(commandBuffer, &VfeStateParams));
}
// Add media flush command in case HW not cleaning the media state
if (MEDIA_IS_WA(m_renderHal->pWaTable, WaMSFWithNoWatermarkTSGHang))
{
FlushParam.bFlushToGo = true;
if (m_walkerType == WALKER_TYPE_MEDIA)
{
FlushParam.ui8InterfaceDescriptorOffset = m_mediaWalkerParams.InterfaceDescriptorOffset;
}
else
{
RENDER_PACKET_ASSERTMESSAGE("ERROR, pWalkerParams is nullptr and cannot get InterfaceDescriptorOffset.");
}
RENDER_PACKET_CHK_STATUS_RETURN(pMhwMiInterface->AddMediaStateFlush(commandBuffer, nullptr, &FlushParam));
}
else if (MEDIA_IS_WA(m_renderHal->pWaTable, WaAddMediaStateFlushCmd))
{
RENDER_PACKET_CHK_STATUS_RETURN(pMhwMiInterface->AddMediaStateFlush(commandBuffer, nullptr, &FlushParam));
}
if (pBatchBuffer)
{
// Send Batch Buffer end command (HW/OS dependent)
RENDER_PACKET_CHK_STATUS_RETURN(pMhwMiInterface->AddMiBatchBufferEnd(commandBuffer, nullptr));
}
else if (IsMiBBEndNeeded(pOsInterface))
{
// Send Batch Buffer end command for 1st level Batch Buffer
RENDER_PACKET_CHK_STATUS_RETURN(pMhwMiInterface->AddMiBatchBufferEnd(commandBuffer, nullptr));
}
else if (m_renderHal->pOsInterface->bNoParsingAssistanceInKmd)
{
RENDER_PACKET_CHK_STATUS_RETURN(pMhwMiInterface->AddMiBatchBufferEnd(commandBuffer, nullptr));
}
// Return unused command buffer space to OS
pOsInterface->pfnReturnCommandBuffer(pOsInterface, commandBuffer, 0);
MOS_NULL_RENDERING_FLAGS NullRenderingFlags;
NullRenderingFlags =
pOsInterface->pfnGetNullHWRenderFlags(pOsInterface);
if ((NullRenderingFlags.VPLgca ||
NullRenderingFlags.VPGobal) == false)
{
dwSyncTag = m_renderHal->pStateHeap->dwNextTag++;
// Set media state and batch buffer as busy
m_renderHal->pStateHeap->pCurMediaState->bBusy = true;
if (pBatchBuffer)
{
pBatchBuffer->bBusy = true;
pBatchBuffer->dwSyncTag = dwSyncTag;
}
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS RenderCmdPacket::RenderEngineSetup()
{
// pls make sure the context already switched to render/compute engine before submit
RENDER_PACKET_CHK_NULL_RETURN(m_renderHal);
// Register the resource of GSH
RENDER_PACKET_CHK_STATUS_RETURN(m_renderHal->pfnReset(m_renderHal));
// Assign media state
m_renderData.mediaState = m_renderHal->pfnAssignMediaState(m_renderHal, RENDERHAL_COMPONENT_PACKET);
RENDER_PACKET_CHK_NULL_RETURN(m_renderData.mediaState);
// Allocate and reset SSH instance
RENDER_PACKET_CHK_STATUS_RETURN(m_renderHal->pfnAssignSshInstance(m_renderHal));
// Assign and Reset binding table
RENDER_PACKET_CHK_STATUS_RETURN(m_renderHal->pfnAssignBindingTable(
m_renderHal,
&m_renderData.bindingTable));
// Reset a new Binding index from start
m_renderData.bindingTableEntry = 0;
// load kernels before packet submit PipeLine to load kernel
return MOS_STATUS_SUCCESS;
}
MOS_STATUS RenderCmdPacket::InitKernelEntry()
{
if (m_kernelCount == 0)
{
RENDER_PACKET_NORMALMESSAGE("no kernel set up");
return MOS_STATUS_LOAD_LIBRARY_FAILED;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS RenderCmdPacket::SetPowerMode(uint32_t KernelID)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
uint16_t wNumRequestedEUSlices = 1; // Default to 1 slice
uint16_t wNumRequestedSubSlices = 3; // Default to 3 subslice
uint16_t wNumRequestedEUs = 8; // Default to 8 EUs
RENDERHAL_POWEROPTION PowerOption;
bool bSetRequestedSlices = false;
const SseuSetting* pcSSEUTable = nullptr;
RENDER_PACKET_CHK_NULL_RETURN(m_renderHal);
if ((m_renderHal->bRequestSingleSlice) || (m_renderHal->bEUSaturationNoSSD))
{
bSetRequestedSlices = true;
// bEUSaturationNoSSD: No slice shutdown, must request 2 slices [CM EU saturation on].
// bRequestSingleSlice: Always single slice.
wNumRequestedEUSlices = (m_renderHal->bEUSaturationNoSSD) ? 2 : 1;
}
else
{
bSetRequestedSlices = false;
}
if (m_renderHal->sseuTable)
{
pcSSEUTable = (const SseuSetting*)m_renderHal->sseuTable;
}
else
{
RENDER_PACKET_ASSERTMESSAGE("SSEU Table not valid.");
return MOS_STATUS_UNKNOWN;
}
RENDER_PACKET_CHK_NULL_RETURN(pcSSEUTable);
pcSSEUTable += KernelID;
if (!bSetRequestedSlices) // If num Slices is already programmed, then don't change it
{
if (wNumRequestedEUSlices < pcSSEUTable->numSlices)
{
wNumRequestedEUSlices = pcSSEUTable->numSlices;
}
}
wNumRequestedSubSlices = pcSSEUTable->numSubSlices;
wNumRequestedEUs = pcSSEUTable->numEUs;
#if (_DEBUG || _RELEASE_INTERNAL)
// User feature key reads
MOS_USER_FEATURE_VALUE_DATA UserFeatureData;
MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_SSEU_SETTING_OVERRIDE_ID,
&UserFeatureData,
m_osInterface->pOsContext);
if (UserFeatureData.u32Data != 0xDEADC0DE)
{
wNumRequestedEUSlices = UserFeatureData.u32Data & 0xFF; // Bits 0-7
wNumRequestedSubSlices = (UserFeatureData.u32Data >> 8) & 0xFF; // Bits 8-15
wNumRequestedEUs = (UserFeatureData.u32Data >> 16) & 0xFFFF; // Bits 16-31
}
#endif
PowerOption.nSlice = wNumRequestedEUSlices;
PowerOption.nSubSlice = wNumRequestedSubSlices;
PowerOption.nEU = wNumRequestedEUs;
m_renderHal->pfnSetPowerOptionMode(m_renderHal, &PowerOption);
return eStatus;
}
uint32_t RenderCmdPacket::SetSurfaceForHwAccess(PMOS_SURFACE surface, PRENDERHAL_SURFACE_NEXT pRenderSurface, PRENDERHAL_SURFACE_STATE_PARAMS pSurfaceParams, bool bWrite)
{
PMOS_INTERFACE pOsInterface;
PRENDERHAL_SURFACE_STATE_ENTRY pSurfaceEntries[MHW_MAX_SURFACE_PLANES];
int32_t iSurfaceEntries;
int32_t i;
MOS_STATUS eStatus;
RENDERHAL_SURFACE_STATE_PARAMS surfaceParams;
// Initialize Variables
eStatus = MOS_STATUS_SUCCESS;
pOsInterface = m_osInterface;
RENDER_PACKET_CHK_NULL_RETURN(pRenderSurface);
RENDER_PACKET_CHK_NULL_RETURN(pOsInterface);
// Register surfaces for rendering (GfxAddress/Allocation index)
// Register resource
RENDER_PACKET_CHK_STATUS_RETURN(m_osInterface->pfnRegisterResource(
m_osInterface,
&surface->OsResource,
bWrite,
true));
if (!pSurfaceParams)
{
MOS_ZeroMemory(&surfaceParams, sizeof(RENDERHAL_SURFACE_STATE_PARAMS));
pSurfaceParams = &surfaceParams;
}
if (pSurfaceParams->bAVS)
{
pSurfaceParams->Type = m_renderHal->SurfaceTypeAdvanced;
}
else
{
pSurfaceParams->Type = m_renderHal->SurfaceTypeDefault;
}
RENDER_PACKET_CHK_STATUS_RETURN(InitRenderHalSurface(
*surface,
pRenderSurface));
if (bWrite)
{
pRenderSurface->SurfType = RENDERHAL_SURF_OUT_RENDERTARGET;
}
// Setup surface states-----------------------------------------------------
RENDER_PACKET_CHK_STATUS_RETURN(m_renderHal->pfnSetupSurfaceState(
m_renderHal,
pRenderSurface,
pSurfaceParams,
&iSurfaceEntries, // for most cases, surface entry should only take 1 entry, need align with kerenl design
pSurfaceEntries,
nullptr));
if (m_renderData.bindingTableEntry > 15)
{
RENDER_PACKET_ASSERTMESSAGE("input surface support up to 16 RSS");
m_renderData.bindingTableEntry = 0;
}
uint32_t iBTEntry = m_renderData.bindingTableEntry;
// Bind surface states------------------------------------------------------
for (i = 0; i < iSurfaceEntries; i++, m_renderData.bindingTableEntry++)
{
RENDER_PACKET_CHK_STATUS_RETURN(m_renderHal->pfnBindSurfaceState(
m_renderHal,
m_renderData.bindingTable,
m_renderData.bindingTableEntry,
pSurfaceEntries[i]));
pRenderSurface->Index = m_renderData.bindingTableEntry;
}
return iBTEntry;
}
uint32_t RenderCmdPacket::SetSurfaceForHwAccess(
PMOS_SURFACE surface,
PRENDERHAL_SURFACE_NEXT pRenderSurface,
PRENDERHAL_SURFACE_STATE_PARAMS pSurfaceParams,
uint32_t bindingIndex,
bool bWrite)
{
PMOS_INTERFACE pOsInterface;
PRENDERHAL_SURFACE_STATE_ENTRY pSurfaceEntries[MHW_MAX_SURFACE_PLANES];
int32_t iSurfaceEntries;
int32_t i;
MOS_STATUS eStatus;
RENDERHAL_SURFACE_STATE_PARAMS surfaceParams;
// Initialize Variables
eStatus = MOS_STATUS_SUCCESS;
pOsInterface = m_osInterface;
RENDER_PACKET_CHK_NULL_RETURN(pRenderSurface);
RENDER_PACKET_CHK_NULL_RETURN(pOsInterface);
// Register surfaces for rendering (GfxAddress/Allocation index)
// Register resource
RENDER_PACKET_CHK_STATUS_RETURN(m_osInterface->pfnRegisterResource(
m_osInterface,
&surface->OsResource,
bWrite,
true));
if (!pSurfaceParams)
{
MOS_ZeroMemory(&surfaceParams, sizeof(RENDERHAL_SURFACE_STATE_PARAMS));
pSurfaceParams = &surfaceParams;
}
if (pSurfaceParams->bAVS)
{
pSurfaceParams->Type = m_renderHal->SurfaceTypeAdvanced;
}
else
{
pSurfaceParams->Type = m_renderHal->SurfaceTypeDefault;
}
RENDER_PACKET_CHK_STATUS_RETURN(InitRenderHalSurface(
*surface,
pRenderSurface));
if (bWrite)
{
pRenderSurface->SurfType = RENDERHAL_SURF_OUT_RENDERTARGET;
}
// Setup surface states-----------------------------------------------------
RENDER_PACKET_CHK_STATUS_RETURN(m_renderHal->pfnSetupSurfaceState(
m_renderHal,
pRenderSurface,
pSurfaceParams,
&iSurfaceEntries, // for most cases, surface entry should only take 1 entry, need align with kerenl design
pSurfaceEntries,
nullptr));
uint32_t iBTEntry = bindingIndex;
// Bind surface states------------------------------------------------------
for (i = 0; i < iSurfaceEntries; i++, iBTEntry++)
{
RENDER_PACKET_CHK_STATUS_RETURN(m_renderHal->pfnBindSurfaceState(
m_renderHal,
m_renderData.bindingTable,
iBTEntry,
pSurfaceEntries[i]));
pRenderSurface->Index = iBTEntry;
}
return bindingIndex;
}
uint32_t RenderCmdPacket::SetBufferForHwAccess(PMOS_SURFACE buffer, PRENDERHAL_SURFACE_NEXT pRenderSurface, PRENDERHAL_SURFACE_STATE_PARAMS pSurfaceParams, bool bWrite)
{
RENDERHAL_SURFACE RenderHalSurface;
RENDERHAL_SURFACE_STATE_PARAMS SurfaceParam;
PRENDERHAL_SURFACE_STATE_ENTRY pSurfaceEntry;
RENDER_PACKET_CHK_NULL_RETURN(m_osInterface);
RENDER_PACKET_CHK_NULL_RETURN(m_osInterface->osCpInterface);
RENDER_PACKET_CHK_NULL_RETURN(buffer);
MOS_ZeroMemory(&RenderHalSurface, sizeof(RenderHalSurface));
// not support CP yet
if (m_osInterface->osCpInterface->IsHMEnabled())
{
RENDER_PACKET_ASSERTMESSAGE("ERROR, need to use VpHal_CommonSetBufferSurfaceForHwAccess if under CP HM.");
}
// Register surfaces for rendering (GfxAddress/Allocation index)
// Register resource
RENDER_PACKET_CHK_STATUS_RETURN(m_osInterface->pfnRegisterResource(
m_osInterface,
&buffer->OsResource,
bWrite,
true));
// Setup Buffer surface-----------------------------------------------------
if (pSurfaceParams == nullptr)
{
MOS_ZeroMemory(&SurfaceParam, sizeof(SurfaceParam));
pSurfaceParams = &SurfaceParam;
}
RENDER_PACKET_CHK_STATUS_RETURN(InitRenderHalSurface(
*buffer,
&RenderHalSurface));
RENDER_PACKET_CHK_STATUS_RETURN(m_renderHal->pfnSetupBufferSurfaceState(
m_renderHal,
&RenderHalSurface,
pSurfaceParams,
&pSurfaceEntry));
// Bind surface state-------------------------------------------------------
RENDER_PACKET_CHK_STATUS_RETURN(m_renderHal->pfnBindSurfaceState(
m_renderHal,
m_renderData.bindingTable,
m_renderData.bindingTableEntry,
pSurfaceEntry));
pRenderSurface->Index = m_renderData.bindingTableEntry;
m_renderData.bindingTableEntry++;
return pRenderSurface->Index;
}
uint32_t RenderCmdPacket::SetBufferForHwAccess(MOS_BUFFER buffer, PRENDERHAL_SURFACE_NEXT pRenderSurface, PRENDERHAL_SURFACE_STATE_PARAMS pSurfaceParams, bool bWrite)
{
RENDERHAL_SURFACE RenderHalSurface;
RENDERHAL_SURFACE_STATE_PARAMS SurfaceParam;
PRENDERHAL_SURFACE_STATE_ENTRY pSurfaceEntry;
RENDER_PACKET_CHK_NULL_RETURN(m_osInterface);
RENDER_PACKET_CHK_NULL_RETURN(m_osInterface->osCpInterface);
MOS_ZeroMemory(&RenderHalSurface, sizeof(RenderHalSurface));
// not support CP yet
if (m_osInterface->osCpInterface->IsHMEnabled())
{
RENDER_PACKET_ASSERTMESSAGE("ERROR, need to use VpHal_CommonSetBufferSurfaceForHwAccess if under CP HM.");
}
// Register surfaces for rendering (GfxAddress/Allocation index)
// Register resource
RENDER_PACKET_CHK_STATUS_RETURN(m_osInterface->pfnRegisterResource(
m_osInterface,
&buffer.OsResource,
bWrite,
true));
// Setup Buffer surface-----------------------------------------------------
if (pSurfaceParams == nullptr)
{
MOS_ZeroMemory(&SurfaceParam, sizeof(SurfaceParam));
pSurfaceParams = &SurfaceParam;
}
RENDER_PACKET_CHK_STATUS_RETURN(InitRenderHalBuffer(
buffer,
&RenderHalSurface));
RENDER_PACKET_CHK_STATUS_RETURN(m_renderHal->pfnSetupBufferSurfaceState(
m_renderHal,
&RenderHalSurface,
pSurfaceParams,
&pSurfaceEntry));
// Bind surface state-------------------------------------------------------
RENDER_PACKET_CHK_STATUS_RETURN(m_renderHal->pfnBindSurfaceState(
m_renderHal,
m_renderData.bindingTable,
m_renderData.bindingTableEntry,
pSurfaceEntry));
pRenderSurface->Index = m_renderData.bindingTableEntry;
m_renderData.bindingTableEntry++;
return pRenderSurface->Index;
}
MOS_STATUS RenderCmdPacket::SetupCurbe(void* pData, uint32_t curbeLength, uint32_t maximumNumberofThreads)
{
m_renderData.iCurbeOffset = m_renderHal->pfnLoadCurbeData(
m_renderHal,
m_renderData.mediaState,
pData,
curbeLength);
if (m_renderData.iCurbeOffset < 0)
{
RENDER_PACKET_ASSERTMESSAGE("Curbe Set Fail, return error");
return MOS_STATUS_UNKNOWN;
}
m_renderData.iCurbeLength = curbeLength;
RENDER_PACKET_CHK_STATUS_RETURN(m_renderHal->pfnSetVfeStateParams(
m_renderHal,
MEDIASTATE_DEBUG_COUNTER_FREE_RUNNING,
maximumNumberofThreads,
m_renderData.iCurbeLength,
m_renderData.iInlineLength,
nullptr));
return MOS_STATUS_SUCCESS;
}
MOS_STATUS RenderCmdPacket::PrepareMediaWalkerParams(KERNEL_WALKER_PARAMS params, MHW_WALKER_PARAMS& mediaWalker)
{
uint32_t uiMediaWalkerBlockSize;
RECT alignedRect = {};
bool bVerticalPattern = false;
uiMediaWalkerBlockSize = m_renderHal->pHwSizes->dwSizeMediaWalkerBlock;
alignedRect = params.alignedRect;
bVerticalPattern = params.rotationNeeded;
// Calculate aligned output area in order to determine the total # blocks
// to process in case of non-16x16 aligned target.
alignedRect.right += uiMediaWalkerBlockSize - 1;
alignedRect.bottom += uiMediaWalkerBlockSize - 1;
alignedRect.left -= alignedRect.left % uiMediaWalkerBlockSize;
alignedRect.top -= alignedRect.top % uiMediaWalkerBlockSize;
alignedRect.right -= alignedRect.right % uiMediaWalkerBlockSize;
alignedRect.bottom -= alignedRect.bottom % uiMediaWalkerBlockSize;
// Set walker cmd params - Rasterscan
mediaWalker.InterfaceDescriptorOffset = params.iMediaID;
mediaWalker.dwGlobalLoopExecCount = 1;
if (uiMediaWalkerBlockSize == 32)
{
mediaWalker.ColorCountMinusOne = 3;
}
else
{
mediaWalker.ColorCountMinusOne = 0;
}
if (alignedRect.left != 0 || alignedRect.top != 0)
{
// if the rect starts from any other macro block other than the first
// then the global resolution should be the whole frame and the global
// start should be the rect start.
mediaWalker.GlobalResolution.x =
(alignedRect.right / uiMediaWalkerBlockSize);
mediaWalker.GlobalResolution.y =
(alignedRect.bottom / uiMediaWalkerBlockSize);
}
else
{
mediaWalker.GlobalResolution.x = params.iBlocksX;
mediaWalker.GlobalResolution.y = params.iBlocksY;
}
mediaWalker.GlobalStart.x =
(alignedRect.left / uiMediaWalkerBlockSize);
mediaWalker.GlobalStart.y =
(alignedRect.top / uiMediaWalkerBlockSize);
mediaWalker.GlobalOutlerLoopStride.x = params.iBlocksX;
mediaWalker.GlobalOutlerLoopStride.y = 0;
mediaWalker.GlobalInnerLoopUnit.x = 0;
mediaWalker.GlobalInnerLoopUnit.y = params.iBlocksY;
mediaWalker.BlockResolution.x = params.iBlocksX;
mediaWalker.BlockResolution.y = params.iBlocksY;
mediaWalker.LocalStart.x = 0;
mediaWalker.LocalStart.y = 0;
if (bVerticalPattern)
{
mediaWalker.LocalOutLoopStride.x = 1;
mediaWalker.LocalOutLoopStride.y = 0;
mediaWalker.LocalInnerLoopUnit.x = 0;
mediaWalker.LocalInnerLoopUnit.y = 1;
mediaWalker.dwLocalLoopExecCount = params.iBlocksX - 1;
mediaWalker.LocalEnd.x = 0;
mediaWalker.LocalEnd.y = params.iBlocksY - 1;
}
else
{
mediaWalker.LocalOutLoopStride.x = 0;
mediaWalker.LocalOutLoopStride.y = 1;
mediaWalker.LocalInnerLoopUnit.x = 1;
mediaWalker.LocalInnerLoopUnit.y = 0;
mediaWalker.dwLocalLoopExecCount = params.iBlocksY - 1;
mediaWalker.LocalEnd.x = params.iBlocksX - 1;
mediaWalker.LocalEnd.y = 0;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS RenderCmdPacket::PrepareComputeWalkerParams(KERNEL_WALKER_PARAMS params, MHW_GPGPU_WALKER_PARAMS& gpgpuWalker)
{
uint32_t uiMediaWalkerBlockSize;
RECT alignedRect = {};
// Get media walker kernel block size
uiMediaWalkerBlockSize = m_renderHal->pHwSizes->dwSizeMediaWalkerBlock;
alignedRect = params.alignedRect;
// Calculate aligned output area in order to determine the total # blocks
// to process in case of non-16x16 aligned target.
alignedRect.right += uiMediaWalkerBlockSize - 1;
alignedRect.bottom += uiMediaWalkerBlockSize - 1;
alignedRect.left -= alignedRect.left % uiMediaWalkerBlockSize;
alignedRect.top -= alignedRect.top % uiMediaWalkerBlockSize;
alignedRect.right -= alignedRect.right % uiMediaWalkerBlockSize;
alignedRect.bottom -= alignedRect.bottom % uiMediaWalkerBlockSize;
// Set walker cmd params - Rasterscan
gpgpuWalker.InterfaceDescriptorOffset = m_renderData.mediaID;
gpgpuWalker.GroupStartingX = (alignedRect.left / uiMediaWalkerBlockSize);
gpgpuWalker.GroupStartingY = (alignedRect.top / uiMediaWalkerBlockSize);
gpgpuWalker.GroupWidth = params.iBlocksX;
gpgpuWalker.GroupHeight = params.iBlocksY;
gpgpuWalker.ThreadWidth = COMPUTE_WALKER_THREAD_SPACE_WIDTH;
gpgpuWalker.ThreadHeight = COMPUTE_WALKER_THREAD_SPACE_HEIGHT;
gpgpuWalker.ThreadDepth = COMPUTE_WALKER_THREAD_SPACE_DEPTH;
gpgpuWalker.IndirectDataStartAddress = m_renderData.iCurbeOffset;
// Indirect Data Length is a multiple of 64 bytes (size of L3 cacheline). Bits [5:0] are zero.
gpgpuWalker.IndirectDataLength = MOS_ALIGN_CEIL(params.iCurbeLength, 1 << MHW_COMPUTE_INDIRECT_SHIFT);
gpgpuWalker.BindingTableID = m_renderData.bindingTable;
return MOS_STATUS_SUCCESS;
}
MOS_STATUS RenderCmdPacket::LoadKernel()
{
int32_t iKrnAllocation;
MHW_KERNEL_PARAM MhwKernelParam;
RENDERHAL_KERNEL_PARAM KernelParam;
// Load kernel to GSH
INIT_MHW_KERNEL_PARAM(MhwKernelParam, &m_renderData.KernelEntry);
INIT_KERNEL_CONFIG_PARAM(KernelParam, &m_renderData.KernelParam);
iKrnAllocation = m_renderHal->pfnLoadKernel(
m_renderHal,
&KernelParam,
&MhwKernelParam,
nullptr);
if (iKrnAllocation < 0)
{
RENDER_PACKET_ASSERTMESSAGE("kernel load failed");
return MOS_STATUS_UNKNOWN;
}
if (m_renderData.iCurbeOffset < 0)
{
RENDER_PACKET_ASSERTMESSAGE("Curbe Set Fail, return error");
return MOS_STATUS_UNKNOWN;
}
// Allocate Media ID, link to kernel
m_renderData.mediaID = m_renderHal->pfnAllocateMediaID(
m_renderHal,
iKrnAllocation,
m_renderData.bindingTable,
m_renderData.iCurbeOffset,
(m_renderData.iCurbeLength),
0,
nullptr);
if (m_renderData.mediaID < 0)
{
RENDER_PACKET_ASSERTMESSAGE("Allocate Media ID failed, return error");
return MOS_STATUS_UNKNOWN;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS RenderCmdPacket::InitRenderHalSurface(MOS_SURFACE surface, PRENDERHAL_SURFACE pRenderSurface)
{
RENDER_PACKET_CHK_NULL_RETURN(pRenderSurface);
RENDERHAL_GET_SURFACE_INFO info;
MOS_ZeroMemory(&info, sizeof(info));
RENDER_PACKET_CHK_STATUS_RETURN(RenderHal_GetSurfaceInfo(
m_renderHal->pOsInterface,
&info,
&surface));
if (Mos_ResourceIsNull(&pRenderSurface->OsSurface.OsResource))
{
pRenderSurface->OsSurface = surface;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS RenderCmdPacket::InitRenderHalBuffer(MOS_BUFFER surface, PRENDERHAL_SURFACE pRenderSurface)
{
RENDER_PACKET_CHK_NULL_RETURN(pRenderSurface);
pRenderSurface->OsSurface.OsResource = surface.OsResource;
pRenderSurface->OsSurface.dwWidth = surface.size;
pRenderSurface->OsSurface.dwHeight = 1;
pRenderSurface->OsSurface.dwPitch = surface.size;
pRenderSurface->OsSurface.Format = Format_RAW;
return MOS_STATUS_SUCCESS;
}