1 /*
2 * Copyright (c) 2021-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_prob_update_packet.cpp
24 //! \brief    Defines the interface for huc prob update packet for VP9 decode
25 //!
26 #include "decode_huc_prob_update_packet.h"
27 #include "mhw_vdbox.h"
28 #include "decode_resource_auto_lock.h"
29 
30 namespace decode
31 {
AllocateResources()32 MOS_STATUS HucVp9ProbUpdatePkt::AllocateResources()
33 {
34     m_dmemBufferSize = MOS_ALIGN_CEIL(sizeof(HucVp9ProbBss), CODECHAL_CACHELINE_SIZE);
35     if (m_probUpdateDmemBufferArray == nullptr)
36     {
37         m_probUpdateDmemBufferArray = m_allocator->AllocateBufferArray(
38             m_dmemBufferSize, "DmemBuffer", m_numVp9ProbUpdateDmem, resourceInternalReadWriteCache, lockableVideoMem);
39         DECODE_CHK_NULL(m_probUpdateDmemBufferArray);
40     }
41 
42     if (m_interProbSaveBuffer == nullptr)
43     {
44         uint32_t interProbSaveBufferSize = MOS_ALIGN_CEIL(CODECHAL_VP9_INTER_PROB_SIZE, CODECHAL_PAGE_SIZE);
45         m_interProbSaveBuffer            = m_allocator->AllocateBuffer(
46             interProbSaveBufferSize, "VP9InterProbsSaveBuffer", resourceInternalReadWriteCache, notLockableVideoMem);
47         DECODE_CHK_NULL(m_interProbSaveBuffer);
48     }
49 
50     return MOS_STATUS_SUCCESS;
51 }
52 
~HucVp9ProbUpdatePkt()53 HucVp9ProbUpdatePkt::~HucVp9ProbUpdatePkt()
54 {
55     if (m_allocator != nullptr)
56     {
57         if (m_probUpdateDmemBufferArray)
58         {
59             m_allocator->Destroy(m_probUpdateDmemBufferArray);
60         }
61 
62         if (m_interProbSaveBuffer)
63         {
64             m_allocator->Destroy(m_interProbSaveBuffer);
65         }
66     }
67 }
68 
Init()69 MOS_STATUS HucVp9ProbUpdatePkt::Init()
70 {
71     DECODE_FUNC_CALL();
72     DECODE_CHK_STATUS(DecodeHucBasic::Init());
73 
74     m_vp9BasicFeature = dynamic_cast<Vp9BasicFeature *>(m_basicFeature);
75     DECODE_CHK_NULL(m_vp9BasicFeature);
76 
77     MHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams;
78     DECODE_CHK_STATUS(m_hwInterface->GetHucStateCommandSize(CODECHAL_DECODE_MODE_VP9VLD, &m_pictureStatesSize, &m_picturePatchListSize, &stateCmdSizeParams));
79 
80     uint32_t cpCmdsize        = 0;
81     uint32_t cpPatchListSize  = 0;
82     m_hwInterface->GetCpInterface()->GetCpSliceLevelCmdSize(cpCmdsize, cpPatchListSize);
83     m_sliceStatesSize += cpCmdsize;
84     m_slicePatchListSize += cpPatchListSize;
85 
86     return MOS_STATUS_SUCCESS;
87 }
88 
Prepare()89 MOS_STATUS HucVp9ProbUpdatePkt::Prepare()
90 {
91     DECODE_FUNC_CALL();
92     PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL);
93 
94     DECODE_CHK_STATUS(SetDmemBuffer());
95     return MOS_STATUS_SUCCESS;
96 }
97 
Submit(MOS_COMMAND_BUFFER * commandBuffer,uint8_t packetPhase)98 MOS_STATUS HucVp9ProbUpdatePkt::Submit(MOS_COMMAND_BUFFER *commandBuffer, uint8_t packetPhase)
99 {
100     DECODE_FUNC_CALL();
101     PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL);
102 
103     DECODE_CHK_NULL(commandBuffer);
104     DECODE_CHK_STATUS(Execute(*commandBuffer, true));
105 
106     return MOS_STATUS_SUCCESS;
107 }
108 
Execute(MOS_COMMAND_BUFFER & cmdBuffer,bool prologNeeded)109 MOS_STATUS HucVp9ProbUpdatePkt::Execute(MOS_COMMAND_BUFFER &cmdBuffer, bool prologNeeded)
110 {
111     PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL);
112 
113     DECODE_CHK_NULL(m_hucItf);
114 
115     if (prologNeeded)
116     {
117         DECODE_CHK_STATUS(AddForceWakeup(cmdBuffer, false, true));
118         DECODE_CHK_STATUS(SendPrologCmds(cmdBuffer));
119     }
120 
121     DECODE_CHK_STATUS(PackPictureLevelCmds(cmdBuffer));
122     DECODE_CHK_STATUS(PackSliceLevelCmds(cmdBuffer));
123     DECODE_CHK_STATUS(VdPipelineFlush(cmdBuffer));
124     DECODE_CHK_STATUS(MemoryFlush(cmdBuffer));
125     DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_BATCH_BUFFER_END(&cmdBuffer, nullptr));
126 
127     return MOS_STATUS_SUCCESS;
128 }
129 
PackPictureLevelCmds(MOS_COMMAND_BUFFER & cmdBuffer)130 MOS_STATUS HucVp9ProbUpdatePkt::PackPictureLevelCmds(MOS_COMMAND_BUFFER &cmdBuffer)
131 {
132     PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL);
133 
134     DECODE_CHK_STATUS(AddCmd_HUC_IMEM_STATE(cmdBuffer));
135     DECODE_CHK_STATUS(AddCmd_HUC_PIPE_MODE_SELECT(cmdBuffer));
136 
137     SETPAR_AND_ADDCMD(HUC_DMEM_STATE, m_hucItf, &cmdBuffer);
138     SETPAR_AND_ADDCMD(HUC_VIRTUAL_ADDR_STATE, m_hucItf, &cmdBuffer);
139 
140     return MOS_STATUS_SUCCESS;
141 }
142 
PackSliceLevelCmds(MOS_COMMAND_BUFFER & cmdBuffer)143 MOS_STATUS HucVp9ProbUpdatePkt::PackSliceLevelCmds(MOS_COMMAND_BUFFER &cmdBuffer)
144 {
145     PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL);
146 
147     SETPAR_AND_ADDCMD(HUC_START, m_hucItf, &cmdBuffer);
148     return MOS_STATUS_SUCCESS;
149 }
150 
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)151 MOS_STATUS HucVp9ProbUpdatePkt::CalculateCommandSize(uint32_t &commandBufferSize, uint32_t &requestedPatchListSize)
152 {
153     DECODE_FUNC_CALL();
154 
155     commandBufferSize      = CalculateCommandBufferSize();
156     requestedPatchListSize = CalculatePatchListSize();
157 
158     return MOS_STATUS_SUCCESS;
159 }
160 
CalculateCommandBufferSize()161 uint32_t HucVp9ProbUpdatePkt::CalculateCommandBufferSize()
162 {
163     DECODE_FUNC_CALL();
164 
165     uint32_t commandBufferSize = m_pictureStatesSize + m_sliceStatesSize;
166     return (commandBufferSize + COMMAND_BUFFER_RESERVED_SPACE);
167 }
168 
CalculatePatchListSize()169 uint32_t HucVp9ProbUpdatePkt::CalculatePatchListSize()
170 {
171     DECODE_FUNC_CALL();
172 
173     if (!m_osInterface->bUsesPatchList)
174     {
175         return 0;
176     }
177 
178     uint32_t requestedPatchListSize = m_picturePatchListSize + m_slicePatchListSize;
179     return requestedPatchListSize;
180 }
181 
SetDmemBuffer()182 MOS_STATUS HucVp9ProbUpdatePkt::SetDmemBuffer()
183 {
184     DECODE_FUNC_CALL();
185 
186     m_probUpdateDmemBuffer = m_probUpdateDmemBufferArray->Fetch();
187     DECODE_CHK_NULL(m_probUpdateDmemBuffer);
188 
189     ResourceAutoLock resLock(m_allocator, &m_probUpdateDmemBuffer->OsResource);
190     HucVp9ProbBss *  dmemBase = (HucVp9ProbBss *)resLock.LockResourceForWrite();
191     DECODE_CHK_NULL(dmemBase);
192 
193     dmemBase->bSegProbCopy     = m_vp9BasicFeature->m_probUpdateFlags.bSegProbCopy;
194     dmemBase->bProbSave        = m_vp9BasicFeature->m_probUpdateFlags.bProbSave;
195     dmemBase->bProbRestore     = m_vp9BasicFeature->m_probUpdateFlags.bProbRestore;
196     dmemBase->bProbReset       = m_vp9BasicFeature->m_probUpdateFlags.bProbReset;
197     dmemBase->bResetFull       = m_vp9BasicFeature->m_probUpdateFlags.bResetFull;
198     dmemBase->bResetKeyDefault = m_vp9BasicFeature->m_probUpdateFlags.bResetKeyDefault;
199     MOS_SecureMemcpy(dmemBase->SegTreeProbs, 7, m_vp9BasicFeature->m_probUpdateFlags.SegTreeProbs, 7);
200     MOS_SecureMemcpy(dmemBase->SegPredProbs, 3, m_vp9BasicFeature->m_probUpdateFlags.SegPredProbs, 3);
201 
202     return MOS_STATUS_SUCCESS;
203 }
204 
VdPipelineFlush(MOS_COMMAND_BUFFER & cmdBuffer)205 MOS_STATUS HucVp9ProbUpdatePkt::VdPipelineFlush(MOS_COMMAND_BUFFER &cmdBuffer)
206 {
207     DECODE_FUNC_CALL();
208 
209     auto &par = m_vdencItf->GETPAR_VD_PIPELINE_FLUSH();
210     par       = {};
211     par.waitDoneHEVC = 1;
212     par.flushHEVC    = 1;
213     par.waitDoneVDCmdMsgParser = 1;
214     m_vdencItf->ADDCMD_VD_PIPELINE_FLUSH(&cmdBuffer);
215 
216     return MOS_STATUS_SUCCESS;
217 }
218 
AddCmd_HUC_IMEM_STATE(MOS_COMMAND_BUFFER & cmdBuffer)219 MOS_STATUS HucVp9ProbUpdatePkt::AddCmd_HUC_IMEM_STATE(MOS_COMMAND_BUFFER &cmdBuffer)
220 {
221     DECODE_FUNC_CALL();
222     auto &par = m_hucItf->MHW_GETPAR_F(HUC_IMEM_STATE)();
223     par                  = {};
224     par.kernelDescriptor = m_vdboxHucVp9ProbUpdateKernelDescriptor;
225     DECODE_CHK_STATUS(m_hucItf->MHW_ADDCMD_F(HUC_IMEM_STATE)(&cmdBuffer));
226     auto &mfxWaitParams               = m_miItf->MHW_GETPAR_F(MFX_WAIT)();
227     mfxWaitParams                     = {};
228     mfxWaitParams.iStallVdboxPipeline = true;
229     DECODE_CHK_STATUS((m_miItf->MHW_ADDCMD_F(MFX_WAIT)(&cmdBuffer)));
230     return MOS_STATUS_SUCCESS;
231 }
232 
AddCmd_HUC_PIPE_MODE_SELECT(MOS_COMMAND_BUFFER & cmdBuffer)233 MOS_STATUS HucVp9ProbUpdatePkt::AddCmd_HUC_PIPE_MODE_SELECT(MOS_COMMAND_BUFFER &cmdBuffer)
234 {
235     DECODE_FUNC_CALL();
236     //for gen 11+, we need to add MFX wait for both KIN and VRT before and after HUC Pipemode select...
237     auto &mfxWaitParams               = m_miItf->MHW_GETPAR_F(MFX_WAIT)();
238     mfxWaitParams                     = {};
239     mfxWaitParams.iStallVdboxPipeline = true;
240     DECODE_CHK_STATUS((m_miItf->MHW_ADDCMD_F(MFX_WAIT)(&cmdBuffer)));
241     auto &par = m_hucItf->MHW_GETPAR_F(HUC_PIPE_MODE_SELECT)();
242 
243     par                            = {};
244     par.mediaSoftResetCounterValue = 2400;
245     par.streamOutEnabled           = false;
246     DECODE_CHK_STATUS(m_hucItf->MHW_ADDCMD_F(HUC_PIPE_MODE_SELECT)(&cmdBuffer));
247 
248     mfxWaitParams                     = {};
249     mfxWaitParams.iStallVdboxPipeline = true;
250     DECODE_CHK_STATUS((m_miItf->MHW_ADDCMD_F(MFX_WAIT)(&cmdBuffer)));
251     return MOS_STATUS_SUCCESS;
252 }
253 
MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE,HucVp9ProbUpdatePkt)254 MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE, HucVp9ProbUpdatePkt)
255 {
256     DECODE_FUNC_CALL();
257     params.hucDataSource = &m_probUpdateDmemBuffer->OsResource;
258     params.dataLength    = MOS_ALIGN_CEIL(m_dmemBufferSize, CODECHAL_CACHELINE_SIZE);
259     params.dmemOffset    = HUC_DMEM_OFFSET_RTOS_GEMS;
260     return MOS_STATUS_SUCCESS;
261 }
262 
MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE,HucVp9ProbUpdatePkt)263 MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE, HucVp9ProbUpdatePkt)
264 {
265     DECODE_FUNC_CALL();
266 
267     PMOS_BUFFER vp9ProbBuffer = m_vp9BasicFeature->m_resVp9ProbBuffer[m_vp9BasicFeature->m_frameCtxIdx];
268     DECODE_ASSERT(vp9ProbBuffer != nullptr);
269     params.regionParams[3].presRegion = &vp9ProbBuffer->OsResource;
270     params.regionParams[3].isWritable = true;
271     params.regionParams[4].presRegion = &m_interProbSaveBuffer->OsResource;
272     params.regionParams[4].isWritable = true;
273 
274     return MOS_STATUS_SUCCESS;
275 }
276 
MHW_SETPAR_DECL_SRC(HUC_START,HucVp9ProbUpdatePkt)277 MHW_SETPAR_DECL_SRC(HUC_START, HucVp9ProbUpdatePkt)
278 {
279     DECODE_FUNC_CALL();
280 
281     params.lastStreamObject = true;
282 
283     return MOS_STATUS_SUCCESS;
284 }
285 
286 }  // namespace decode
287