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 ©Params)
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 ©Params = 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 ©Params = 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