1 /*
2 * Copyright (c) 2019-2024, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     decode_huc_copy_packet.cpp
24 //! \brief    Defines the interface for huc copy packet
25 //!
26 #include "decode_huc_copy_packet.h"
27 #include "mhw_vdbox.h"
28 #include "decode_pipeline.h"
29 
30 namespace decode
31 {
PushCopyParams(HucCopyParams & copyParams)32 MOS_STATUS HucCopyPkt::PushCopyParams(HucCopyParams &copyParams)
33 {
34     DECODE_CHK_COND(copyParams.copyLength <= 0, "HucCopyPkt: Invalid copy params!");
35 
36     m_copyParamsList.push_back(copyParams);
37 
38     return MOS_STATUS_SUCCESS;
39 }
40 
Submit(MOS_COMMAND_BUFFER * commandBuffer,uint8_t packetPhase)41 MOS_STATUS HucCopyPkt::Submit(MOS_COMMAND_BUFFER *commandBuffer, uint8_t packetPhase)
42 {
43     DECODE_FUNC_CALL();
44     DECODE_CHK_NULL(commandBuffer);
45 
46     bool firstTaskInPhase = packetPhase & firstPacket;
47     bool requestProlog    = false;
48 
49     if ((!m_pipeline->IsSingleTaskPhaseSupported() || firstTaskInPhase) && (m_pipeline->GetPipeNum() == 1))
50     {
51         // Send command buffer header at the beginning (OS dependent)
52         requestProlog = true;
53     }
54     DECODE_CHK_STATUS(Execute(*commandBuffer, requestProlog));
55 
56     return MOS_STATUS_SUCCESS;
57 }
58 
Execute(MOS_COMMAND_BUFFER & cmdBuffer,bool prologNeeded)59 MOS_STATUS HucCopyPkt::Execute(MOS_COMMAND_BUFFER &cmdBuffer, bool prologNeeded)
60 {
61     DECODE_FUNC_CALL();
62     DECODE_CHK_NULL(m_hucItf);
63 
64     SetPerfTag();
65 
66     for (m_copyParamsIdx = 0; m_copyParamsIdx < m_copyParamsList.size(); m_copyParamsIdx++)
67     {
68         if (prologNeeded && (m_copyParamsIdx == 0))
69         {
70             DECODE_CHK_STATUS(SendPrologCmds(cmdBuffer));
71         }
72 
73         DECODE_CHK_STATUS(AddCmd_HUC_PIPE_MODE_SELECT(cmdBuffer));
74         SETPAR_AND_ADDCMD(HUC_IND_OBJ_BASE_ADDR_STATE, m_hucItf, &cmdBuffer);
75         DECODE_CHK_STATUS(AddHucIndState(cmdBuffer));
76         SETPAR_AND_ADDCMD(HUC_STREAM_OBJECT, m_hucItf, &cmdBuffer);
77 
78         // Flush the engine to ensure memory written out
79         DECODE_CHK_STATUS(MemoryFlush(cmdBuffer));
80 
81         DECODE_CHK_STATUS(m_allocator->SyncOnResource(m_copyParamsList[m_copyParamsIdx].srcBuffer, false));
82         DECODE_CHK_STATUS(m_allocator->SyncOnResource(m_copyParamsList[m_copyParamsIdx].destBuffer, true));
83     }
84 
85     // clear copy params since it is consumed
86     m_copyParamsList.clear();
87 
88     return MOS_STATUS_SUCCESS;
89 }
90 
AddCmd_HUC_PIPE_MODE_SELECT(MOS_COMMAND_BUFFER & cmdBuffer)91 MOS_STATUS HucCopyPkt::AddCmd_HUC_PIPE_MODE_SELECT(MOS_COMMAND_BUFFER &cmdBuffer)
92 {
93     DECODE_FUNC_CALL();
94     //for gen 11+, we need to add MFX wait for both KIN and VRT before and after HUC Pipemode select...
95     auto &mfxWaitParams               = m_miItf->MHW_GETPAR_F(MFX_WAIT)();
96     mfxWaitParams                     = {};
97     mfxWaitParams.iStallVdboxPipeline = true;
98     DECODE_CHK_STATUS((m_miItf->MHW_ADDCMD_F(MFX_WAIT)(&cmdBuffer)));
99 
100     auto &par = m_hucItf->MHW_GETPAR_F(HUC_PIPE_MODE_SELECT)();
101     par                                     = {};
102     par.mediaSoftResetCounterValue          = 2400;
103     par.streamOutEnabled                    = true;
104     par.disableProtectionSetting            = true;
105     DECODE_CHK_STATUS(m_hucItf->MHW_ADDCMD_F(HUC_PIPE_MODE_SELECT)(&cmdBuffer));
106 
107     mfxWaitParams                     = {};
108     mfxWaitParams.iStallVdboxPipeline = true;
109     DECODE_CHK_STATUS((m_miItf->MHW_ADDCMD_F(MFX_WAIT)(&cmdBuffer)));
110     return MOS_STATUS_SUCCESS;
111 }
112 
AddHucIndState(MOS_COMMAND_BUFFER & cmdBuffer)113 MOS_STATUS HucCopyPkt::AddHucIndState(MOS_COMMAND_BUFFER &cmdBuffer)
114 {
115     return MOS_STATUS_SUCCESS;
116 }
117 
MHW_SETPAR_DECL_SRC(HUC_IND_OBJ_BASE_ADDR_STATE,HucCopyPkt)118 MHW_SETPAR_DECL_SRC(HUC_IND_OBJ_BASE_ADDR_STATE, HucCopyPkt)
119 {
120     DECODE_FUNC_CALL();
121 
122     const HucCopyParams &copyParams = m_copyParamsList.at(m_copyParamsIdx);
123 
124     uint32_t dataSize            = copyParams.srcOffset + copyParams.copyLength;
125     uint32_t dataOffset          = MOS_ALIGN_FLOOR(copyParams.srcOffset, MHW_PAGE_SIZE);
126     uint32_t inputRelativeOffset = copyParams.srcOffset - dataOffset;
127 
128     uint32_t destSize             = copyParams.destOffset + copyParams.copyLength;
129     uint32_t destOffset           = MOS_ALIGN_FLOOR(copyParams.destOffset, MHW_PAGE_SIZE);
130     uint32_t outputRelativeOffset = copyParams.destOffset - destOffset;
131 
132     // Enlarge the stream in/out data size to avoid upper bound hit assert in HuC
133     dataSize += inputRelativeOffset;
134     destSize += outputRelativeOffset;
135 
136     // pass bit-stream buffer by Ind Obj Addr command
137     params.DataBuffer            = copyParams.srcBuffer;
138     params.DataSize              = MOS_ALIGN_CEIL(dataSize, MHW_PAGE_SIZE);
139     params.DataOffset            = dataOffset;
140     params.StreamOutObjectBuffer = copyParams.destBuffer;
141     params.StreamOutObjectSize   = MOS_ALIGN_CEIL(destSize, MHW_PAGE_SIZE);
142     params.StreamOutObjectOffset = destOffset;
143 
144     return MOS_STATUS_SUCCESS;
145 }
146 
MHW_SETPAR_DECL_SRC(HUC_STREAM_OBJECT,HucCopyPkt)147 MHW_SETPAR_DECL_SRC(HUC_STREAM_OBJECT, HucCopyPkt)
148 {
149     DECODE_FUNC_CALL();
150 
151     const HucCopyParams &copyParams = m_copyParamsList.at(m_copyParamsIdx);
152 
153     uint32_t dataOffset          = MOS_ALIGN_FLOOR(copyParams.srcOffset, MHW_PAGE_SIZE);
154     uint32_t inputRelativeOffset = copyParams.srcOffset - dataOffset;
155 
156     uint32_t destOffset           = MOS_ALIGN_FLOOR(copyParams.destOffset, MHW_PAGE_SIZE);
157     uint32_t outputRelativeOffset = copyParams.destOffset - destOffset;
158 
159     // set stream object with stream out enabled
160     params.IndirectStreamInDataLength    = copyParams.copyLength;
161     params.IndirectStreamInStartAddress  = inputRelativeOffset;
162     params.IndirectStreamOutStartAddress = outputRelativeOffset;
163     params.HucProcessing                 = true;
164     params.HucBitstreamEnable            = true;
165     params.StreamOut                     = true;
166 
167     return MOS_STATUS_SUCCESS;
168 }
169 
SetPerfTag()170 void HucCopyPkt::SetPerfTag()
171 {
172     DECODE_FUNC_CALL();
173 
174     uint16_t perfTag = ((m_basicFeature->m_mode << 4) & 0xF0) | COPY_TYPE;
175     m_osInterface->pfnSetPerfTag(m_osInterface, perfTag);
176 }
177 
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)178 MOS_STATUS HucCopyPkt::CalculateCommandSize(uint32_t &commandBufferSize, uint32_t &requestedPatchListSize)
179 {
180     DECODE_FUNC_CALL();
181 
182     uint32_t                       hucCommandsSize  = 0;
183     uint32_t                       hucPatchListSize = 0;
184     MHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams;
185 
186     if (m_hwInterface)
187     {
188         DECODE_CHK_STATUS(m_hwInterface->GetHucStateCommandSize(
189             m_basicFeature->m_mode, (uint32_t *)&hucCommandsSize, (uint32_t *)&hucPatchListSize, &stateCmdSizeParams));
190     }
191 
192     commandBufferSize      = hucCommandsSize;
193     requestedPatchListSize = m_osInterface->bUsesPatchList ? hucPatchListSize : 0;
194 
195     // 4K align since allocation is in chunks of 4K bytes.
196     commandBufferSize = MOS_ALIGN_CEIL(commandBufferSize, 0x1000);
197 
198     return MOS_STATUS_SUCCESS;
199 }
200 
201 }  // namespace decode
202