blob: 14f27f12fe05a555ddb0d077459c6333a6d2e839 [file] [log] [blame]
/*
* Copyright (c) 2017-2018, 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 mhw_vdbox_huc_generic.h
//! \brief MHW interface for constructing HUC commands for the Vdbox engine
//! \details Impelements shared Vdbox HUC command construction functions across all platforms as templates
//!
#ifndef _MHW_VDBOX_HUC_GENERIC_H_
#define _MHW_VDBOX_HUC_GENERIC_H_
#include "mhw_vdbox_huc_interface.h"
//! MHW Vdbox Huc generic interface
/*!
This class defines the shared Huc command construction functions across all platforms as templates
*/
template <class THucCmds, class TMiCmds>
class MhwVdboxHucInterfaceGeneric : public MhwVdboxHucInterface
{
protected:
#define PATCH_LIST_COMMAND(x) (x##_NUMBER_OF_ADDRESSES)
//!
//! \enum CommandsNumberOfAddresses
//! \brief Commands number of addresses
//!
enum CommandsNumberOfAddresses
{
MI_STORE_DATA_IMM_CMD_NUMBER_OF_ADDRESSES = 1, // 2 DW for 1 address field
MI_FLUSH_DW_CMD_NUMBER_OF_ADDRESSES = 1, // 2 DW for 1 address field
MI_CONDITIONAL_BATCH_BUFFER_END_CMD_NUMBER_OF_ADDRESSES = 1, // 2 DW for 1 address field
MI_STORE_REGISTER_MEM_CMD_NUMBER_OF_ADDRESSES = 1, // 2 DW for 1 address field
MI_COPY_MEM_MEM_CMD_NUMBER_OF_ADDRESSES = 2, // 4 DW for 2 address fields
VD_PIPELINE_FLUSH_CMD_NUMBER_OF_ADDRESSES = 0, // 0 DW for 0 address fields
HUC_PIPE_MODE_SELECT_CMD_NUMBER_OF_ADDRESSES = 0, // 0 DW for address fields
HUC_IMEM_STATE_CMD_NUMBER_OF_ADDRESSES = 0, // 0 DW for address fields
HUC_DMEM_STATE_CMD_NUMBER_OF_ADDRESSES = 2, // 3 DW for 2 address fields
HUC_VIRTUAL_ADDR_STATE_CMD_NUMBER_OF_ADDRESSES = 16, // 32 DW for 16 address fields
HUC_IND_OBJ_BASE_ADDR_STATE_CMD_NUMBER_OF_ADDRESSES = 4, // 8 DW for 4 address fields
HUC_STREAM_OBJECT_CMD_NUMBER_OF_ADDRESSES = 0, // 0 DW for address fields
HUC_START_CMD_NUMBER_OF_ADDRESSES = 0, // 0 DW for address fields
};
//!
//! \brief Constructor
//!
MhwVdboxHucInterfaceGeneric(
PMOS_INTERFACE osInterface,
MhwMiInterface *miInterface,
MhwCpInterface *cpInterface) :
MhwVdboxHucInterface(osInterface, miInterface, cpInterface)
{
MHW_FUNCTION_ENTER;
}
//!
//! \brief Destructor
//!
virtual ~MhwVdboxHucInterfaceGeneric() {}
protected:
MOS_STATUS GetHucStateCommandSize(
uint32_t mode,
uint32_t *commandsSize,
uint32_t *patchListSize,
PMHW_VDBOX_STATE_CMDSIZE_PARAMS params)
{
MHW_FUNCTION_ENTER;
uint32_t maxSize = 0;
uint32_t patchListMaxSize = 0;
uint32_t standard = CodecHal_GetStandardFromMode(mode);
uint32_t numSlices = 1;
uint32_t numStoreDataImm = 1;
uint32_t numStoreReg = 1;
MHW_MI_CHK_NULL(commandsSize);
MHW_MI_CHK_NULL(patchListSize);
MHW_MI_CHK_NULL(params);
if(params->uNumStoreDataImm)
{
numStoreDataImm = params->uNumStoreDataImm;
}
if(params->uNumStoreReg)
{
numStoreReg = params->uNumStoreReg;
}
if (mode == CODECHAL_DECODE_MODE_HEVCVLD && params->bShortFormat)
{
numSlices = CODECHAL_HEVC_MAX_NUM_SLICES_LVL_6;
numStoreDataImm = 2;
numStoreReg = 2;
maxSize +=
2 * TMiCmds::MI_CONDITIONAL_BATCH_BUFFER_END_CMD::byteSize;
patchListMaxSize +=
2 * PATCH_LIST_COMMAND(MI_CONDITIONAL_BATCH_BUFFER_END_CMD);
}
else if (standard == CODECHAL_CENC)
{
numStoreDataImm = 3;
numStoreReg = 3;
maxSize +=
TMiCmds::MI_FLUSH_DW_CMD::byteSize * 2 +
TMiCmds::MI_BATCH_BUFFER_END_CMD::byteSize;
patchListMaxSize +=
PATCH_LIST_COMMAND(MI_FLUSH_DW_CMD) * 2;
}
else if (mode == CODECHAL_ENCODE_MODE_VP9)
{
// for huc status 2 register and semaphore signal and reset
numStoreDataImm = 3;
maxSize +=
TMiCmds::MI_BATCH_BUFFER_END_CMD::byteSize +
TMiCmds::MI_FLUSH_DW_CMD::byteSize;
patchListMaxSize +=
PATCH_LIST_COMMAND(MI_FLUSH_DW_CMD);
}
else if (mode == CODECHAL_ENCODE_MODE_AVC)
{
numStoreDataImm = 2;
numStoreReg = 2;
maxSize +=
2 * TMiCmds::MI_CONDITIONAL_BATCH_BUFFER_END_CMD::byteSize;
patchListMaxSize +=
2 * PATCH_LIST_COMMAND(MI_CONDITIONAL_BATCH_BUFFER_END_CMD);
}
maxSize +=
THucCmds::HUC_PIPE_MODE_SELECT_CMD::byteSize +
THucCmds::HUC_IMEM_STATE_CMD::byteSize +
THucCmds::HUC_DMEM_STATE_CMD::byteSize +
THucCmds::HUC_VIRTUAL_ADDR_STATE_CMD::byteSize +
THucCmds::HUC_IND_OBJ_BASE_ADDR_STATE_CMD::byteSize +
numSlices * THucCmds::HUC_STREAM_OBJECT_CMD::byteSize +
numSlices * THucCmds::HUC_START_CMD::byteSize +
numStoreDataImm * TMiCmds::MI_STORE_DATA_IMM_CMD::byteSize +
numStoreReg * TMiCmds::MI_STORE_REGISTER_MEM_CMD::byteSize;
if(params->uNumMfxWait)
{
maxSize +=
params->uNumMfxWait * TMiCmds::MFX_WAIT_CMD::byteSize;
}
patchListMaxSize +=
PATCH_LIST_COMMAND(HUC_PIPE_MODE_SELECT_CMD) +
PATCH_LIST_COMMAND(HUC_IMEM_STATE_CMD) +
PATCH_LIST_COMMAND(HUC_DMEM_STATE_CMD) +
PATCH_LIST_COMMAND(HUC_VIRTUAL_ADDR_STATE_CMD) +
PATCH_LIST_COMMAND(HUC_IND_OBJ_BASE_ADDR_STATE_CMD) +
numSlices * PATCH_LIST_COMMAND(HUC_STREAM_OBJECT_CMD) +
numSlices * PATCH_LIST_COMMAND(HUC_START_CMD) +
numStoreDataImm * PATCH_LIST_COMMAND(MI_STORE_DATA_IMM_CMD) +
numStoreReg * PATCH_LIST_COMMAND(MI_STORE_REGISTER_MEM_CMD);
if(params->uNumAddConBBEnd)
{
maxSize +=
params->uNumAddConBBEnd * TMiCmds::MI_CONDITIONAL_BATCH_BUFFER_END_CMD::byteSize;
patchListMaxSize +=
params->uNumAddConBBEnd * PATCH_LIST_COMMAND(MI_CONDITIONAL_BATCH_BUFFER_END_CMD);
}
if(params->uNumMiCopy)
{
maxSize +=
params->uNumMiCopy * TMiCmds::MI_COPY_MEM_MEM_CMD::byteSize;
patchListMaxSize +=
params->uNumMiCopy * PATCH_LIST_COMMAND(MI_COPY_MEM_MEM_CMD);
}
if(params->uNumMiFlush)
{
maxSize +=
params->uNumMiFlush * TMiCmds::MI_FLUSH_DW_CMD::byteSize;
patchListMaxSize +=
params->uNumMiFlush * PATCH_LIST_COMMAND(MI_FLUSH_DW_CMD);
}
if (params->bHucDummyStream || params->bPerformHucStreamOut)
{
uint32_t dummyTimes = params->bPerformHucStreamOut ? 2: 1;
for (uint32_t i = 0; i < dummyTimes; i++)
{
maxSize +=
THucCmds::HUC_PIPE_MODE_SELECT_CMD::byteSize +
THucCmds::HUC_IMEM_STATE_CMD::byteSize +
THucCmds::HUC_DMEM_STATE_CMD::byteSize +
THucCmds::HUC_VIRTUAL_ADDR_STATE_CMD::byteSize +
THucCmds::HUC_IND_OBJ_BASE_ADDR_STATE_CMD::byteSize +
THucCmds::HUC_STREAM_OBJECT_CMD::byteSize +
THucCmds::HUC_START_CMD::byteSize +
TMiCmds::MI_FLUSH_DW_CMD::byteSize;
patchListMaxSize +=
PATCH_LIST_COMMAND(HUC_PIPE_MODE_SELECT_CMD) +
PATCH_LIST_COMMAND(HUC_IMEM_STATE_CMD) +
PATCH_LIST_COMMAND(HUC_DMEM_STATE_CMD) +
PATCH_LIST_COMMAND(HUC_VIRTUAL_ADDR_STATE_CMD) +
PATCH_LIST_COMMAND(HUC_IND_OBJ_BASE_ADDR_STATE_CMD) +
PATCH_LIST_COMMAND(HUC_STREAM_OBJECT_CMD) +
PATCH_LIST_COMMAND(HUC_START_CMD) +
PATCH_LIST_COMMAND(MI_FLUSH_DW_CMD);
}
if (params->bPerformHucStreamOut)
{
maxSize +=
THucCmds::HUC_PIPE_MODE_SELECT_CMD::byteSize +
THucCmds::HUC_IND_OBJ_BASE_ADDR_STATE_CMD::byteSize +
THucCmds::HUC_STREAM_OBJECT_CMD::byteSize +
4 * TMiCmds::MI_FLUSH_DW_CMD::byteSize;
patchListMaxSize +=
PATCH_LIST_COMMAND(HUC_PIPE_MODE_SELECT_CMD) +
PATCH_LIST_COMMAND(HUC_IND_OBJ_BASE_ADDR_STATE_CMD) +
PATCH_LIST_COMMAND(HUC_STREAM_OBJECT_CMD) +
4 * PATCH_LIST_COMMAND(MI_FLUSH_DW_CMD);
}
}
*commandsSize = maxSize;
*patchListSize = patchListMaxSize;
return MOS_STATUS_SUCCESS;
}
MOS_STATUS GetHucPrimitiveCommandSize(
uint32_t mode,
uint32_t *commandsSize,
uint32_t *patchListSize)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
uint32_t maxSize = 0;
uint32_t patchListMaxSize = 0;
// Hal will handling the multiplication of cmd size instead of MHW
*commandsSize = maxSize;
*patchListSize = patchListMaxSize;
return eStatus;
}
MOS_STATUS AddHucPipeModeSelectCmd(
MOS_COMMAND_BUFFER *cmdBuffer,
MHW_VDBOX_PIPE_MODE_SELECT_PARAMS *params)
{
MHW_MI_CHK_NULL(cmdBuffer);
MHW_MI_CHK_NULL(params);
typename THucCmds::HUC_PIPE_MODE_SELECT_CMD cmd;
if (!params->disableProtectionSetting)
{
MHW_MI_CHK_STATUS(m_cpInterface->SetProtectionSettingsForHucPipeModeSelect((uint32_t*)&cmd));
}
cmd.DW1.IndirectStreamOutEnable = params->bStreamOutEnabled;
cmd.DW2.MediaSoftResetCounterPer1000Clocks = params->dwMediaSoftResetCounterValue;
MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, cmd.byteSize));
return MOS_STATUS_SUCCESS;
}
MOS_STATUS AddHucImemStateCmd(
MOS_COMMAND_BUFFER *cmdBuffer,
MHW_VDBOX_HUC_IMEM_STATE_PARAMS *params)
{
MHW_MI_CHK_NULL(cmdBuffer);
MHW_MI_CHK_NULL(params);
typename THucCmds::HUC_IMEM_STATE_CMD cmd;
cmd.DW4.HucFirmwareDescriptor = params->dwKernelDescriptor;
MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, cmd.byteSize));
return MOS_STATUS_SUCCESS;
}
MOS_STATUS AddHucDmemStateCmd(
MOS_COMMAND_BUFFER *cmdBuffer,
MHW_VDBOX_HUC_DMEM_STATE_PARAMS *params)
{
MHW_MI_CHK_NULL(cmdBuffer);
MHW_MI_CHK_NULL(params);
MHW_RESOURCE_PARAMS resourceParams;
MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
resourceParams.dwLsbNum = MHW_VDBOX_HUC_GENERAL_STATE_SHIFT;
resourceParams.HwCommandType = MOS_HUC_DMEM;
typename THucCmds::HUC_DMEM_STATE_CMD cmd;
if (params->presHucDataSource)
{
resourceParams.presResource = params->presHucDataSource;
resourceParams.dwOffset = 0;
resourceParams.pdwCmd = (cmd.HucDataSourceBaseAddress.DW0_1.Value);
resourceParams.dwLocationInCmd = 1;
resourceParams.bIsWritable = false;
MHW_MI_CHK_STATUS(AddResourceToCmd(
m_osInterface,
cmdBuffer,
&resourceParams));
// set HuC data destination address
cmd.DW4.HucDataDestinationBaseAddress = params->dwDmemOffset >> MHW_VDBOX_HUC_GENERAL_STATE_SHIFT;
// set data length
cmd.DW5.HucDataLength = params->dwDataLength >> MHW_VDBOX_HUC_GENERAL_STATE_SHIFT;
}
MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, cmd.byteSize));
return MOS_STATUS_SUCCESS;
}
MOS_STATUS AddHucVirtualAddrStateCmd(
MOS_COMMAND_BUFFER *cmdBuffer,
MHW_VDBOX_HUC_VIRTUAL_ADDR_PARAMS *params)
{
MHW_MI_CHK_NULL(cmdBuffer);
MHW_MI_CHK_NULL(params);
MHW_RESOURCE_PARAMS resourceParams;
// set up surface 0~15
MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
resourceParams.dwLsbNum = MHW_VDBOX_HUC_UPPER_BOUND_STATE_SHIFT;
resourceParams.HwCommandType = MOS_HUC_VIRTUAL_ADDR;
typename THucCmds::HUC_VIRTUAL_ADDR_STATE_CMD cmd;
for (int i = 0; i < 16; i++)
{
if (params->regionParams[i].presRegion)
{
cmd.HucVirtualAddressRegion[i].HucSurfaceVirtualaddrregion015.DW0.Value |=
m_cacheabilitySettings[MOS_CODEC_RESOURCE_USAGE_HUC_VIRTUAL_ADDR_REGION_BUFFER_CODEC].Value;
resourceParams.presResource = params->regionParams[i].presRegion;
resourceParams.dwOffset = params->regionParams[i].dwOffset;
resourceParams.bIsWritable = params->regionParams[i].isWritable;
resourceParams.pdwCmd = cmd.HucVirtualAddressRegion[i].HucSurfaceBaseAddressVirtualaddrregion015.DW0_1.Value;
resourceParams.dwLocationInCmd = 1 + (i * 3);
MHW_MI_CHK_STATUS(AddResourceToCmd(
m_osInterface,
cmdBuffer,
&resourceParams));
}
}
MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, cmd.byteSize));
return MOS_STATUS_SUCCESS;
}
MOS_STATUS AddHucIndObjBaseAddrStateCmd(
MOS_COMMAND_BUFFER *cmdBuffer,
MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS *params)
{
MHW_MI_CHK_NULL(cmdBuffer);
MHW_MI_CHK_NULL(params);
MHW_RESOURCE_PARAMS resourceParams;
// base address of the bit-stream buffer
MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
resourceParams.dwLsbNum = MHW_VDBOX_HUC_UPPER_BOUND_STATE_SHIFT;
resourceParams.dwUpperBoundLocationOffsetFromCmd = 3;
resourceParams.HwCommandType = MOS_HUC_IND_OBJ_BASE_ADDR;
typename THucCmds::HUC_IND_OBJ_BASE_ADDR_STATE_CMD cmd;
if (params->presDataBuffer)
{
resourceParams.presResource = params->presDataBuffer;
resourceParams.dwOffset = params->dwDataOffset;
resourceParams.pdwCmd = cmd.HucIndirectStreamInObjectbaseAddress.DW0_1.Value;
resourceParams.dwLocationInCmd = 1;
resourceParams.bIsWritable = false;
resourceParams.dwSize = params->dwDataSize;
MHW_MI_CHK_STATUS(AddResourceToCmd(
m_osInterface,
cmdBuffer,
&resourceParams));
}
if (params->presStreamOutObjectBuffer)
{
// base address of the stream out buffer
resourceParams.presResource = params->presStreamOutObjectBuffer;
resourceParams.dwOffset = params->dwStreamOutObjectOffset;
resourceParams.pdwCmd = cmd.HucIndirectStreamOutObjectbaseAddress.DW0_1.Value;
resourceParams.dwLocationInCmd = 6;
resourceParams.bIsWritable = true;
resourceParams.dwSize = params->dwStreamOutObjectSize;
MHW_MI_CHK_STATUS(AddResourceToCmd(
m_osInterface,
cmdBuffer,
&resourceParams));
}
MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, cmd.byteSize));
return MOS_STATUS_SUCCESS;
}
MOS_STATUS AddHucStreamObjectCmd(
MOS_COMMAND_BUFFER *cmdBuffer,
MHW_VDBOX_HUC_STREAM_OBJ_PARAMS *params)
{
MHW_MI_CHK_NULL(cmdBuffer);
MHW_MI_CHK_NULL(params);
typename THucCmds::HUC_STREAM_OBJECT_CMD cmd;
cmd.DW1.IndirectStreamInDataLength = params->dwIndStreamInLength;
cmd.DW2.IndirectStreamInStartAddress = params->dwIndStreamInStartAddrOffset;
cmd.DW2.HucProcessing = params->bHucProcessing;
cmd.DW3.IndirectStreamOutStartAddress = params->dwIndStreamOutStartAddrOffset;
cmd.DW4.HucBitstreamEnable = params->bStreamInEnable;
cmd.DW4.StreamOut = params->bStreamOutEnable;
cmd.DW4.EmulationPreventionByteRemoval = params->bEmulPreventionByteRemoval;
cmd.DW4.StartCodeSearchEngine = params->bStartCodeSearchEngine;
cmd.DW4.Drmlengthmode = params->bLengthModeEnabled;
cmd.DW4.StartCodeByte2 = params->ucStartCodeByte2;
cmd.DW4.StartCodeByte1 = params->ucStartCodeByte1;
cmd.DW4.StartCodeByte0 = params->ucStartCodeByte0;
MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, cmd.byteSize));
return MOS_STATUS_SUCCESS;
}
MOS_STATUS AddHucStartCmd(
MOS_COMMAND_BUFFER *cmdBuffer,
bool lastStreamObject)
{
MHW_MI_CHK_NULL(cmdBuffer);
typename THucCmds::HUC_START_CMD cmd;
// set last stream object or not
cmd.DW1.Laststreamobject = (lastStreamObject != 0);
MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, cmd.byteSize));
return MOS_STATUS_SUCCESS;
}
};
#endif