/*
* Copyright (c) 2014-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     mhw_render_generic.h
//! \brief    MHW interface templates for render engine commands
//! \details  Impelements shared HW command construction functions across all platforms as templates
//!

#ifndef __MHW_RENDER_GENERIC_H__
#define __MHW_RENDER_GENERIC_H__

#include "mhw_render.h"

template <class TRenderCmds>
class MhwRenderInterfaceGeneric : public MhwRenderInterface
{
protected:
    MhwRenderInterfaceGeneric(
        MhwMiInterface          *miInterface,
        PMOS_INTERFACE          osInterface,
        MEDIA_SYSTEM_INFO       *gtSystemInfo,
        uint8_t                 newStateHeapManagerRequested) :
        MhwRenderInterface(miInterface, osInterface, gtSystemInfo, newStateHeapManagerRequested){}

public:
    virtual ~MhwRenderInterfaceGeneric() { MHW_FUNCTION_ENTER; }

    MOS_STATUS AddPipelineSelectCmd(
        PMOS_COMMAND_BUFFER             cmdBuffer,
        bool                            gpGpuPipe)
    {
        MHW_FUNCTION_ENTER;

        MHW_MI_CHK_NULL(cmdBuffer);

        typename TRenderCmds::PIPELINE_SELECT_CMD  cmd;
        cmd.DW0.PipelineSelection = (gpGpuPipe) ? cmd.PIPELINE_SELECTION_GPGPU : cmd.PIPELINE_SELECTION_MEDIA;

        MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, cmd.byteSize));

        return MOS_STATUS_SUCCESS;
    }

    MOS_STATUS AddStateBaseAddrCmd(
        PMOS_COMMAND_BUFFER                 cmdBuffer,
        PMHW_STATE_BASE_ADDR_PARAMS         params)
    {
        MHW_FUNCTION_ENTER;

        MHW_MI_CHK_NULL(cmdBuffer);
        MHW_MI_CHK_NULL(params);

        MHW_RESOURCE_PARAMS resourceParams;
        MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
        resourceParams.dwLsbNum      = MHW_RENDER_ENGINE_STATE_BASE_ADDRESS_SHIFT;
        resourceParams.HwCommandType = MOS_STATE_BASE_ADDR;

        typename TRenderCmds::STATE_BASE_ADDRESS_CMD cmd;

        if (params->presGeneralState)
        {
            cmd.DW1_2.GeneralStateBaseAddressModifyEnable    = true;
            cmd.DW12.GeneralStateBufferSizeModifyEnable      = true;
            cmd.DW1_2.GeneralStateMemoryObjectControlState   = params->mocs4GeneralState;
            resourceParams.presResource                      = params->presGeneralState;
            resourceParams.dwOffset                          = 0;
            resourceParams.pdwCmd                            = cmd.DW1_2.Value;
            resourceParams.dwLocationInCmd                   = 1;

            // upper bound of the allocated resource will not be set
            resourceParams.dwUpperBoundLocationOffsetFromCmd = 0;

            MHW_MI_CHK_STATUS(AddResourceToCmd(
                m_osInterface,
                cmdBuffer,
                &resourceParams));

            cmd.DW12.GeneralStateBufferSize = (params->dwGeneralStateSize + MHW_PAGE_SIZE - 1) / MHW_PAGE_SIZE;
        }

        if (m_osInterface->bNoParsingAssistanceInKmd)
        {
            uint32_t indirectStateOffset, indirectStateSize;
            MHW_MI_CHK_STATUS(m_osInterface->pfnGetIndirectState(m_osInterface, &indirectStateOffset, &indirectStateSize));

            // When KMD parsing assistance is not used,
            // UMD is required to set up the SSH
            // in the STATE_BASE_ADDRESS command.
            // All addresses used in the STATE_BASE_ADDRESS
            // command need to have the modify
            // bit associated with it set to 1.
            cmd.DW4_5.SurfaceStateBaseAddressModifyEnable    = true;
            cmd.DW4_5.SurfaceStateMemoryObjectControlState   = params->mocs4SurfaceState;
            resourceParams.presResource                      = &cmdBuffer->OsResource;
            resourceParams.dwOffset                          = indirectStateOffset;
            resourceParams.pdwCmd                            = cmd.DW4_5.Value;
            resourceParams.dwLocationInCmd                   = 4;

            // upper bound of the allocated resource will not be set
            resourceParams.dwUpperBoundLocationOffsetFromCmd = 0;

            MHW_MI_CHK_STATUS(AddResourceToCmd(
                m_osInterface,
                cmdBuffer,
                &resourceParams));
        }

        if (params->presDynamicState)
        {
            cmd.DW6_7.DynamicStateBaseAddressModifyEnable    = true;
            cmd.DW6_7.DynamicStateMemoryObjectControlState   = params->mocs4DynamicState;
            cmd.DW13.DynamicStateBufferSizeModifyEnable      = true;
            resourceParams.presResource                      = params->presDynamicState;
            resourceParams.dwOffset                          = 0;
            resourceParams.pdwCmd                            = cmd.DW6_7.Value;
            resourceParams.dwLocationInCmd                   = 6;
            resourceParams.bIsWritable                       = params->bDynamicStateRenderTarget;

            // upper bound of the allocated resource will not be set
            resourceParams.dwUpperBoundLocationOffsetFromCmd = 0;

            MHW_MI_CHK_STATUS(AddResourceToCmd(
                m_osInterface,
                cmdBuffer,
                &resourceParams));

            cmd.DW13.DynamicStateBufferSize                  = (params->dwDynamicStateSize + MHW_PAGE_SIZE - 1) / MHW_PAGE_SIZE;

            //Reset bRenderTarget as it should be enabled only for Dynamic State
            resourceParams.bIsWritable = false;
        }

        if (params->presIndirectObjectBuffer)
        {
            cmd.DW8_9.IndirectObjectBaseAddressModifyEnable     = true;
            cmd.DW8_9.IndirectObjectMemoryObjectControlState    = params->mocs4IndirectObjectBuffer;
            cmd.DW14.IndirectObjectBufferSizeModifyEnable       = true;
            resourceParams.presResource                         = params->presIndirectObjectBuffer;
            resourceParams.dwOffset                             = 0;
            resourceParams.pdwCmd                               = cmd.DW8_9.Value;
            resourceParams.dwLocationInCmd                      = 8;

            // upper bound of the allocated resource will not be set
            resourceParams.dwUpperBoundLocationOffsetFromCmd    = 0;

            MHW_MI_CHK_STATUS(AddResourceToCmd(
                m_osInterface,
                cmdBuffer,
                &resourceParams));

            cmd.DW14.IndirectObjectBufferSize                   = (params->dwIndirectObjectBufferSize + MHW_PAGE_SIZE - 1) / MHW_PAGE_SIZE;
        }

        if (params->presInstructionBuffer)
        {
            cmd.DW10_11.InstructionBaseAddressModifyEnable   = true;
            cmd.DW15.InstructionBufferSizeModifyEnable       = true;
            cmd.DW10_11.InstructionMemoryObjectControlState  = params->mocs4InstructionCache;
            resourceParams.presResource                      = params->presInstructionBuffer;
            resourceParams.dwOffset                          = 0;
            resourceParams.pdwCmd                            = cmd.DW10_11.Value;
            resourceParams.dwLocationInCmd                   = 10;

            // upper bound of the allocated resource will not be set
            resourceParams.dwUpperBoundLocationOffsetFromCmd = 0;

            MHW_MI_CHK_STATUS(AddResourceToCmd(
                m_osInterface,
                cmdBuffer,
                &resourceParams));

            cmd.DW15.InstructionBufferSize = (params->dwInstructionBufferSize + MHW_PAGE_SIZE - 1) / MHW_PAGE_SIZE;
        }

        // stateless dataport access
        cmd.DW3.StatelessDataPortAccessMemoryObjectControlState = params->mocs4StatelessDataport;

        MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, cmd.byteSize));

        return MOS_STATUS_SUCCESS;
    }

    MOS_STATUS AddMediaVfeCmd(
        PMOS_COMMAND_BUFFER             cmdBuffer,
        PMHW_VFE_PARAMS                 params)
    {
        MHW_FUNCTION_ENTER;

        MHW_MI_CHK_NULL(cmdBuffer);
        MHW_MI_CHK_NULL(params);

        typename TRenderCmds::MEDIA_VFE_STATE_CMD cmd;

        if (params->pKernelState)
        {
            MHW_MI_CHK_NULL(params->pKernelState);

            cmd.DW3.MaximumNumberOfThreads          = (params->dwMaximumNumberofThreads) ?
                params->dwMaximumNumberofThreads - 1 : params->pKernelState->KernelParams.iThreadCount - 1;
            cmd.DW5.CurbeAllocationSize             =
                MOS_ROUNDUP_SHIFT(params->pKernelState->KernelParams.iCurbeLength, 5);
            cmd.DW5.UrbEntryAllocationSize          = MOS_MAX(1,
                MOS_ROUNDUP_SHIFT(params->pKernelState->KernelParams.iInlineDataLength, 5));

            uint32_t numberofURBEntries   =
                (m_hwCaps.dwMaxURBSize -
                cmd.DW5.CurbeAllocationSize -
                params->pKernelState->KernelParams.iIdCount) /
                cmd.DW5.UrbEntryAllocationSize;
            numberofURBEntries            = MOS_CLAMP_MIN_MAX(numberofURBEntries, 1, 64);
            cmd.DW3.NumberOfUrbEntries      = numberofURBEntries;
        }
        else
        {
            if (params->dwNumberofURBEntries == 0)
            {
                MHW_ASSERTMESSAGE("Parameter dwNumberofURBEntries is 0 will cause divided by zero.");
                return MOS_STATUS_INVALID_PARAMETER;
            }

            if (params->dwPerThreadScratchSpace)
            {
                cmd.DW1.PerThreadScratchSpace       = params->dwPerThreadScratchSpace;
                cmd.DW1.ScratchSpaceBasePointer     = params->dwScratchSpaceBasePointer >> 10;
                cmd.DW2.ScratchSpaceBasePointerHigh = 0;
            }
            cmd.DW3.MaximumNumberOfThreads          = (params->dwMaximumNumberofThreads) ?
                params->dwMaximumNumberofThreads - 1 : m_hwCaps.dwMaxThreads - 1;
            cmd.DW3.NumberOfUrbEntries              = params->dwNumberofURBEntries;
            cmd.DW5.CurbeAllocationSize             = params->dwCURBEAllocationSize >> 5;
            cmd.DW5.UrbEntryAllocationSize          = (params->dwURBEntryAllocationSize) ?
                params->dwURBEntryAllocationSize :
                (m_hwCaps.dwMaxURBSize -
                cmd.DW5.CurbeAllocationSize -
                m_hwCaps.dwMaxInterfaceDescriptorEntries) /
                params->dwNumberofURBEntries;
        }

        if ((cmd.DW3.NumberOfUrbEntries > m_hwCaps.dwMaxURBEntries) ||
            (cmd.DW5.CurbeAllocationSize > m_hwCaps.dwMaxCURBEAllocationSize) ||
            (cmd.DW5.UrbEntryAllocationSize > m_hwCaps.dwMaxURBEntryAllocationSize) ||
            (cmd.DW3.NumberOfUrbEntries * cmd.DW5.UrbEntryAllocationSize +
            cmd.DW5.CurbeAllocationSize +
            m_hwCaps.dwMaxInterfaceDescriptorEntries > m_hwCaps.dwMaxURBSize))
        {
            MHW_ASSERTMESSAGE("Parameters requested exceed maximum supported by HW.");
            return MOS_STATUS_INVALID_PARAMETER;
        }

        MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, cmd.byteSize));

        return MOS_STATUS_SUCCESS;
    }

    MOS_STATUS AddMediaCurbeLoadCmd(
        PMOS_COMMAND_BUFFER             cmdBuffer,
        PMHW_CURBE_LOAD_PARAMS          params)
    {
        MHW_FUNCTION_ENTER;

        MHW_MI_CHK_NULL(cmdBuffer);
        MHW_MI_CHK_NULL(params);

        typename TRenderCmds::MEDIA_CURBE_LOAD_CMD cmd;

        if (params->pKernelState)
        {
            MHW_MI_CHK_NULL(m_stateHeapInterface->pStateHeapInterface);

            auto kernelState = params->pKernelState;

            cmd.DW2.CurbeTotalDataLength    = (uint32_t)MOS_ALIGN_CEIL(
                kernelState->KernelParams.iCurbeLength,
                m_stateHeapInterface->pStateHeapInterface->GetCurbeAlignment());
            cmd.DW3.CurbeDataStartAddress   = MOS_ALIGN_CEIL(
                (kernelState->m_dshRegion.GetOffset() +
                kernelState->dwCurbeOffset),
                m_stateHeapInterface->pStateHeapInterface->GetCurbeAlignment());
        }
        else
        {
            cmd.DW2.CurbeTotalDataLength    = params->dwCURBETotalDataLength;
            cmd.DW3.CurbeDataStartAddress   = params->dwCURBEDataStartAddress;
        }

        // Send the command only if there is data to load
        if (cmd.DW2.CurbeTotalDataLength)
        {
            MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, cmd.byteSize));
        }
        else
        {
            MHW_NORMALMESSAGE("MEDIA_CURBE_LOAD must load data. Command skipped.");
        }

        return MOS_STATUS_SUCCESS;
    }

    MOS_STATUS AddMediaIDLoadCmd(
        PMOS_COMMAND_BUFFER             cmdBuffer,
        PMHW_ID_LOAD_PARAMS             params)
    {
        MHW_FUNCTION_ENTER;

        MHW_MI_CHK_NULL(cmdBuffer);
        MHW_MI_CHK_NULL(params);
        MHW_MI_CHK_NULL(m_stateHeapInterface->pStateHeapInterface);

        typename TRenderCmds::MEDIA_INTERFACE_DESCRIPTOR_LOAD_CMD cmd;

        if (params->pKernelState)
        {
            auto kernelState = params->pKernelState;

            cmd.DW2.InterfaceDescriptorTotalLength      =
                m_stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData() * params->dwNumKernelsLoaded;
            cmd.DW3.InterfaceDescriptorDataStartAddress = MOS_ALIGN_CEIL(
                kernelState->m_dshRegion.GetOffset() +
                kernelState->dwIdOffset +
                (params->dwIdIdx * m_stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData()),
                m_stateHeapInterface->pStateHeapInterface->GetIdAlignment());
        }
        // Client managed MediaIDs
        else if (params->dwInterfaceDescriptorLength)
        {
            cmd.DW2.InterfaceDescriptorTotalLength      = params->dwInterfaceDescriptorLength;
            cmd.DW3.InterfaceDescriptorDataStartAddress = params->dwInterfaceDescriptorStartOffset;
        }

        if (cmd.DW2.InterfaceDescriptorTotalLength > 0)
        {
            MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, cmd.byteSize));
        }
        else
        {
            MHW_NORMALMESSAGE("MEDIA_INTERFACE_DESCRIPTOR_LOAD must load data. Command skipped.");
        }

        return MOS_STATUS_SUCCESS;
    }

    MOS_STATUS AddMediaObject(
        PMOS_COMMAND_BUFFER             cmdBuffer,
        PMHW_BATCH_BUFFER               batchBuffer,
        PMHW_MEDIA_OBJECT_PARAMS        params)
    {
        MHW_FUNCTION_ENTER;

        MHW_MI_CHK_NULL(params);

        if (cmdBuffer == nullptr && batchBuffer == nullptr)
        {
            MHW_ASSERTMESSAGE("No valid buffer to add the command to!");
            return MOS_STATUS_INVALID_PARAMETER;
        }

        typename TRenderCmds::MEDIA_OBJECT_CMD cmd;

        if (params->dwInlineDataSize > 0)
        {
            cmd.DW0.DwordLength             =
                TRenderCmds::GetOpLength(((params->dwInlineDataSize / sizeof(uint32_t)) + cmd.dwSize));
        }

        cmd.DW1.InterfaceDescriptorOffset   = params->dwInterfaceDescriptorOffset;
        cmd.DW2.IndirectDataLength          = params->dwIndirectLoadLength;
        cmd.DW2.SubsliceDestinationSelect   = params->dwHalfSliceDestinationSelect;
        cmd.DW2.SliceDestinationSelect      = params->dwSliceDestinationSelect;
        cmd.DW2.ForceDestination            = params->bForceDestination;
        cmd.DW3.IndirectDataStartAddress    = params->dwIndirectDataStartAddress;

        MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(
            cmdBuffer,
            batchBuffer,
            &cmd,
            cmd.byteSize));

        if (params->pInlineData && params->dwInlineDataSize > 0)
        {
            MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(
                cmdBuffer,
                batchBuffer,
                params->pInlineData,
                params->dwInlineDataSize));
        }

        return MOS_STATUS_SUCCESS;
    }

    MOS_STATUS AddMediaObjectWalkerCmd(
        PMOS_COMMAND_BUFFER             cmdBuffer,
        PMHW_WALKER_PARAMS              params)
    {
        MHW_FUNCTION_ENTER;

        MHW_MI_CHK_NULL(cmdBuffer);
        MHW_MI_CHK_NULL(params);

        typename TRenderCmds::MEDIA_OBJECT_WALKER_CMD cmd;

        if (params->pInlineData)
        {
            cmd.DW0.DwordLength =
                TRenderCmds::GetOpLength(cmd.dwSize + params->InlineDataLength / sizeof(uint32_t));
        }

        cmd.DW1.InterfaceDescriptorOffset   = params->InterfaceDescriptorOffset;
        cmd.DW5.GroupIdLoopSelect           = params->GroupIdLoopSelect;
        cmd.DW6.ColorCountMinusOne          = params->ColorCountMinusOne;
        cmd.DW6.MiddleLoopExtraSteps        = params->MiddleLoopExtraSteps;
        cmd.DW6.MidLoopUnitX                = params->MidLoopUnitX;
        cmd.DW6.LocalMidLoopUnitY           = params->MidLoopUnitY;
        cmd.DW7.LocalLoopExecCount          = params->dwLocalLoopExecCount;
        cmd.DW7.GlobalLoopExecCount         = params->dwGlobalLoopExecCount;
        cmd.DW8.BlockResolutionX            = params->BlockResolution.x;
        cmd.DW8.BlockResolutionY            = params->BlockResolution.y;
        cmd.DW9.LocalStartX                 = params->LocalStart.x;
        cmd.DW9.LocalStartY                 = params->LocalStart.y;
        cmd.DW11.LocalOuterLoopStrideX      = params->LocalOutLoopStride.x;
        cmd.DW11.LocalOuterLoopStrideY      = params->LocalOutLoopStride.y;
        cmd.DW12.LocalInnerLoopUnitX        = params->LocalInnerLoopUnit.x;
        cmd.DW12.LocalInnerLoopUnitY        = params->LocalInnerLoopUnit.y;
        cmd.DW13.GlobalResolutionX          = params->GlobalResolution.x;
        cmd.DW13.GlobalResolutionY          = params->GlobalResolution.y;
        cmd.DW14.GlobalStartX               = params->GlobalStart.x;
        cmd.DW14.GlobalStartY               = params->GlobalStart.y;
        cmd.DW15.GlobalOuterLoopStrideX     = params->GlobalOutlerLoopStride.x;
        cmd.DW15.GlobalOuterLoopStrideY     = params->GlobalOutlerLoopStride.y;
        cmd.DW16.GlobalInnerLoopUnitX       = params->GlobalInnerLoopUnit.x;
        cmd.DW16.GlobalInnerLoopUnitY       = params->GlobalInnerLoopUnit.y;

        MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, cmd.byteSize));

        if (params->pInlineData)
        {
            if (params->InlineDataLength > 0)
            {
                MHW_MI_CHK_STATUS(Mos_AddCommand(
                    cmdBuffer,
                    params->pInlineData,
                    params->InlineDataLength));
            }
            else
            {
                MHW_NORMALMESSAGE("Inline data indicated, however cannot insert without valid length.");
            }
        }

        return MOS_STATUS_SUCCESS;
    }

    MOS_STATUS AddGpGpuWalkerStateCmd(
        PMOS_COMMAND_BUFFER             cmdBuffer,
        PMHW_GPGPU_WALKER_PARAMS        params)
    {
        MHW_FUNCTION_ENTER;

        MHW_MI_CHK_NULL(cmdBuffer);
        MHW_MI_CHK_NULL(params);

        if (params->ThreadDepth == 0)
        {
            params->ThreadDepth = 1;
        }
        if (params->GroupDepth == 0)
        {
            params->GroupDepth = 1;
        }

        typename TRenderCmds::GPGPU_WALKER_CMD cmd;
        cmd.DW1.InterfaceDescriptorOffset       = params->InterfaceDescriptorOffset;
        cmd.DW4.SimdSize                        = 2; // SIMD32
        cmd.DW4.ThreadWidthCounterMaximum       = params->ThreadWidth - 1;
        cmd.DW4.ThreadHeightCounterMaximum      = params->ThreadHeight - 1;
        cmd.DW4.ThreadDepthCounterMaximum       = params->ThreadDepth - 1;
        cmd.DW5.ThreadGroupIdStartingX          = 0;
        cmd.DW7.ThreadGroupIdXDimension         = params->GroupWidth;
        cmd.DW8.ThreadGroupIdStartingY          = 0;
        cmd.DW10.ThreadGroupIdYDimension        = params->GroupHeight;
        cmd.DW11.ThreadGroupIdStartingResumeZ   = 0;
        cmd.DW12.ThreadGroupIdZDimension        = params->GroupDepth;
        cmd.DW13.RightExecutionMask             = 0xffffffff;
        cmd.DW14.BottomExecutionMask            = 0xffffffff;

        MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, cmd.byteSize));

        return MOS_STATUS_SUCCESS;
    }
    MOS_STATUS AddChromaKeyCmd(
        PMOS_COMMAND_BUFFER             cmdBuffer,
        PMHW_CHROMAKEY_PARAMS           params)
    {
        MHW_FUNCTION_ENTER;

        MHW_MI_CHK_NULL(cmdBuffer);
        MHW_MI_CHK_NULL(params);

        typename TRenderCmds::_3DSTATE_CHROMA_KEY_CMD cmd;
        cmd.DW1.ChromakeyTableIndex = params->dwIndex;
        cmd.DW2.ChromakeyLowValue   = params->dwLow;
        cmd.DW3.ChromakeyHighValue  = params->dwHigh;

        MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, cmd.byteSize));

        return MOS_STATUS_SUCCESS;
    }

    MOS_STATUS AddSipStateCmd(
        PMOS_COMMAND_BUFFER             cmdBuffer,
        PMHW_SIP_STATE_PARAMS           params)
    {
        MHW_FUNCTION_ENTER;

        MHW_MI_CHK_NULL(cmdBuffer);
        MHW_MI_CHK_NULL(params);

        typename TRenderCmds::STATE_SIP_CMD cmd;
        cmd.DW1_2.SystemInstructionPointer = (uint64_t)(params->dwSipBase >> 4);

        MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, cmd.byteSize))

        return MOS_STATUS_SUCCESS;
    }

    inline uint32_t GetMediaObjectCmdSize()
    {
        return TRenderCmds::MEDIA_OBJECT_CMD::byteSize;
    }
};

#endif // __MHW_RENDER_GENERIC_H__
