1 /*
2 * Copyright (c) 2020-2022, 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     encode_vp9_vdenc_packet.cpp
24 //! \brief    Defines the interface for vp9 encode vdenc packet
25 //!
26 
27 #include "encode_vp9_vdenc_packet.h"
28 #include "encode_status_report_defs.h"
29 #include "encode_vp9_hpu.h"
30 #include "encode_vp9_brc.h"
31 #include "encode_vp9_cqp.h"
32 #include "encode_vp9_pak.h"
33 #include "encode_vp9_tile.h"
34 #include "codec_def_common.h"
35 
36 using namespace mhw::vdbox;
37 namespace encode
38 {
~Vp9VdencPkt()39 Vp9VdencPkt::~Vp9VdencPkt()
40 {
41     FreeResources();
42 }
43 
Init()44 MOS_STATUS Vp9VdencPkt::Init()
45 {
46     ENCODE_FUNC_CALL();
47     ENCODE_CHK_NULL_RETURN(m_statusReport);
48     ENCODE_CHK_STATUS_RETURN(CmdPacket::Init());
49 
50     m_basicFeature = dynamic_cast<Vp9BasicFeature *>(m_featureManager->GetFeature(Vp9FeatureIDs::basicFeature));
51     ENCODE_CHK_NULL_RETURN(m_basicFeature);
52 
53 #ifdef _MMC_SUPPORTED
54     m_mmcState = m_pipeline->GetMmcState();
55     ENCODE_CHK_NULL_RETURN(m_mmcState);
56     m_basicFeature->m_mmcState = m_mmcState;
57 #endif
58 
59     m_allocator = m_pipeline->GetEncodeAllocator();
60     ENCODE_CHK_STATUS_RETURN(AllocateResources());
61 
62     ENCODE_CHK_STATUS_RETURN(m_statusReport->RegistObserver(this));
63 
64     CalculatePictureStateCommandSize();
65 
66     uint32_t vdencPictureStatesSize = 0, vdencPicturePatchListSize = 0;
67     GetVdencStateCommandsDataSize(vdencPictureStatesSize, vdencPicturePatchListSize);
68     m_defaultPictureStatesSize += vdencPictureStatesSize;
69     m_defaultPicturePatchListSize += vdencPicturePatchListSize;
70 
71     GetHxxPrimitiveCommandSize();
72 
73     m_usePatchList = m_osInterface->bUsesPatchList;
74 
75     return MOS_STATUS_SUCCESS;
76 }
77 
Prepare()78 MOS_STATUS Vp9VdencPkt::Prepare()
79 {
80     ENCODE_FUNC_CALL();
81 
82     m_pictureStatesSize    = m_defaultPictureStatesSize;
83     m_picturePatchListSize = m_defaultPicturePatchListSize;
84     m_sliceStatesSize      = m_defaultSliceStatesSize;
85     m_slicePatchListSize   = m_defaultSlicePatchListSize;
86 
87     Vp9Pipeline *pipeline = dynamic_cast<Vp9Pipeline *>(m_pipeline);
88     ENCODE_CHK_NULL_RETURN(pipeline);
89 
90     m_vp9SeqParams     = m_basicFeature->m_vp9SeqParams;
91     m_vp9PicParams     = m_basicFeature->m_vp9PicParams;
92     m_vp9SegmentParams = m_basicFeature->m_vp9SegmentParams;
93 
94     ENCODE_CHK_STATUS_RETURN(ValidateVdboxIdx(m_vdboxIndex));
95 
96     ENCODE_CHK_STATUS_RETURN(SetRowstoreCachingOffsets());
97 
98     return MOS_STATUS_SUCCESS;
99 }
100 
Destroy()101 MOS_STATUS Vp9VdencPkt::Destroy()
102 {
103     ENCODE_FUNC_CALL();
104 
105     m_statusReport->UnregistObserver(this);
106 
107     return MOS_STATUS_SUCCESS;
108 }
109 
Completed(void * mfxStatus,void * rcsStatus,void * statusReport)110 MOS_STATUS Vp9VdencPkt::Completed(void *mfxStatus, void *rcsStatus, void *statusReport)
111 {
112     ENCODE_FUNC_CALL();
113 
114     ENCODE_CHK_NULL_RETURN(mfxStatus);
115     ENCODE_CHK_NULL_RETURN(statusReport);
116     ENCODE_CHK_NULL_RETURN(m_basicFeature);
117 
118     EncodeStatusMfx *       encodeStatusMfx  = (EncodeStatusMfx *)mfxStatus;
119     EncodeStatusReportData *statusReportData = (EncodeStatusReportData *)statusReport;
120     if (statusReportData->hwCtr)
121     {
122         m_encodecp->UpdateCpStatusReport(statusReport);
123     }
124 
125     // Update tile status data here if need
126 
127     if (statusReportData->numberTilesInFrame > 1 && m_basicFeature->m_scalableMode)
128     {
129         // When Tile/Scalable mode feature enabled, Reset is not in vdenc packet
130         return MOS_STATUS_SUCCESS;
131     }
132 
133     CODECHAL_DEBUG_TOOL(
134         ENCODE_CHK_STATUS_RETURN(DumpResources(encodeStatusMfx, statusReportData)););
135 
136     m_basicFeature->Reset((CODEC_REF_LIST *)statusReportData->currRefList);
137 
138     return MOS_STATUS_SUCCESS;
139 }
140 
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)141 MOS_STATUS Vp9VdencPkt::CalculateCommandSize(uint32_t &commandBufferSize, uint32_t &requestedPatchListSize)
142 {
143     ENCODE_FUNC_CALL();
144 
145     m_pictureStatesSize    = m_defaultPictureStatesSize;
146     m_picturePatchListSize = m_defaultPicturePatchListSize;
147     m_sliceStatesSize      = m_defaultSliceStatesSize;
148     m_slicePatchListSize   = m_defaultSlicePatchListSize;
149 
150     commandBufferSize      = CalculateCommandBufferSize();
151     requestedPatchListSize = CalculatePatchListSize();
152 
153     return MOS_STATUS_SUCCESS;
154 }
155 
CalculatePictureStateCommandSize()156 MOS_STATUS Vp9VdencPkt::CalculatePictureStateCommandSize()
157 {
158     ENCODE_FUNC_CALL();
159 
160     MHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams;
161     stateCmdSizeParams.bHucDummyStream = true;
162 
163     uint32_t hcpCommandsSize = 0;
164     uint32_t hcpPatchListSize = 0;
165 
166     hcpCommandsSize =
167         m_vdencInterfaceNew->MHW_GETSIZE_F(VD_PIPELINE_FLUSH)() +
168         m_miItf->MHW_GETSIZE_F(MI_FLUSH_DW)() +
169         m_hcpInterfaceNew->MHW_GETSIZE_F(HCP_PIPE_MODE_SELECT)() +
170         m_hcpInterfaceNew->MHW_GETSIZE_F(HCP_SURFACE_STATE)() * 4 +
171         m_hcpInterfaceNew->MHW_GETSIZE_F(HCP_PIPE_BUF_ADDR_STATE)() +
172         m_hcpInterfaceNew->MHW_GETSIZE_F(HCP_IND_OBJ_BASE_ADDR_STATE)() +
173         m_hcpInterfaceNew->MHW_GETSIZE_F(HCP_VP9_SEGMENT_STATE)() * 8 +
174         m_hcpInterfaceNew->MHW_GETSIZE_F(HCP_BSD_OBJECT)() +
175         m_miItf->MHW_GETSIZE_F(MI_LOAD_REGISTER_REG)() * 8;
176 
177     hcpPatchListSize =
178         mhw::vdbox::hcp::Itf::VD_PIPELINE_FLUSH_CMD_NUMBER_OF_ADDRESSES +
179         mhw::vdbox::hcp::Itf::MI_FLUSH_DW_CMD_NUMBER_OF_ADDRESSES +
180         mhw::vdbox::hcp::Itf::HCP_PIPE_MODE_SELECT_CMD_NUMBER_OF_ADDRESSES +
181         mhw::vdbox::hcp::Itf::HCP_SURFACE_STATE_CMD_NUMBER_OF_ADDRESSES * 4 +
182         mhw::vdbox::hcp::Itf::HCP_PIPE_BUF_ADDR_STATE_CMD_NUMBER_OF_ADDRESSES +
183         mhw::vdbox::hcp::Itf::HCP_IND_OBJ_BASE_ADDR_STATE_CMD_NUMBER_OF_ADDRESSES +
184         mhw::vdbox::hcp::Itf::HCP_VP9_SEGMENT_STATE_CMD_NUMBER_OF_ADDRESSES * 8 +
185         mhw::vdbox::hcp::Itf::HCP_BSD_OBJECT_CMD_NUMBER_OF_ADDRESSES;
186 
187     hcpCommandsSize +=
188         m_hcpInterfaceNew->MHW_GETSIZE_F(HCP_VP9_PIC_STATE)() +
189         m_miItf->MHW_GETSIZE_F(MI_FLUSH_DW)() * 2 +
190         m_miItf->MHW_GETSIZE_F(MI_STORE_DATA_IMM)() * 4 +
191         m_miItf->MHW_GETSIZE_F(MI_STORE_REGISTER_MEM)() * 11 +
192         m_miItf->MHW_GETSIZE_F(MI_COPY_MEM_MEM)() * 4 +
193         m_miItf->MHW_GETSIZE_F(MI_BATCH_BUFFER_START)() * 3 +
194         m_miItf->MHW_GETSIZE_F(MI_STORE_DATA_IMM)() * 2 +  // Slice level commands
195         m_miItf->MHW_GETSIZE_F(MI_LOAD_REGISTER_MEM)() * 2 +
196         m_hcpInterfaceNew->MHW_GETSIZE_F(HCP_PAK_INSERT_OBJECT)() * 2 +
197         m_hcpInterfaceNew->MHW_GETSIZE_F(HCP_TILE_CODING)() +
198         m_miItf->MHW_GETSIZE_F(MI_BATCH_BUFFER_START)() +
199         m_miItf->MHW_GETSIZE_F(MI_SEMAPHORE_WAIT)() +     // Use HW wait command for each VDBOX
200         m_miItf->MHW_GETSIZE_F(MI_STORE_DATA_IMM)() * 3;  // One is for reset and another one for set per VDBOX, one for wait
201 
202     hcpCommandsSize += 3 * m_miItf->MHW_GETSIZE_F(VD_CONTROL_STATE)();  // VD_CONTROL_STATE Hcp init + flush + vdenc init
203 
204     hcpPatchListSize +=
205         mhw::vdbox::hcp::Itf::HCP_VP9_PIC_STATE_CMD_NUMBER_OF_ADDRESSES +
206         mhw::vdbox::hcp::Itf::MI_FLUSH_DW_CMD_NUMBER_OF_ADDRESSES * 2 +
207         mhw::vdbox::hcp::Itf::MI_STORE_DATA_IMM_CMD_NUMBER_OF_ADDRESSES * 4 +
208         mhw::vdbox::hcp::Itf::MI_STORE_REGISTER_MEM_CMD_NUMBER_OF_ADDRESSES * 11 +
209         mhw::vdbox::hcp::Itf::MI_COPY_MEM_MEM_CMD_NUMBER_OF_ADDRESSES * 4 +
210         mhw::vdbox::hcp::Itf::MI_BATCH_BUFFER_START_CMD_NUMBER_OF_ADDRESSES * 3 +
211         mhw::vdbox::hcp::Itf::MI_STORE_DATA_IMM_CMD_NUMBER_OF_ADDRESSES * 2 +
212         mhw::vdbox::hcp::Itf::HCP_PAK_INSERT_OBJECT_CMD_NUMBER_OF_ADDRESSES * 2 +
213         mhw::vdbox::hcp::Itf::HCP_TILE_CODING_COMMAND_NUMBER_OF_ADDRESSES +
214         mhw::vdbox::hcp::Itf::MI_BATCH_BUFFER_START_CMD_NUMBER_OF_ADDRESSES +
215         mhw::vdbox::hcp::Itf::MI_STORE_DATA_IMM_CMD_NUMBER_OF_ADDRESSES * 2;
216 
217     uint32_t cpCmdsize = 0;
218     uint32_t cpPatchListSize = 0;
219     if(m_hwInterface->GetCpInterface())
220     {
221         m_hwInterface->GetCpInterface()->GetCpStateLevelCmdSize(cpCmdsize, cpPatchListSize);
222     }
223 
224     uint32_t hucCommandsSize = 0;
225     uint32_t hucPatchListSize = 0;
226     ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucStateCommandSize(
227         CODECHAL_ENCODE_MODE_VP9, (uint32_t *)&hucCommandsSize, (uint32_t *)&hucPatchListSize, &stateCmdSizeParams));
228 
229     m_defaultPictureStatesSize = hcpCommandsSize + hucCommandsSize + cpCmdsize;
230     m_defaultPicturePatchListSize = hcpPatchListSize + hucPatchListSize + cpPatchListSize;
231 
232     return MOS_STATUS_SUCCESS;
233 }
234 
GetVdencStateCommandsDataSize(uint32_t & vdencPictureStatesSize,uint32_t & vdencPicturePatchListSize)235 MOS_STATUS Vp9VdencPkt::GetVdencStateCommandsDataSize(uint32_t &vdencPictureStatesSize, uint32_t &vdencPicturePatchListSize)
236 {
237     ENCODE_FUNC_CALL();
238     ENCODE_CHK_NULL_RETURN(m_hwInterface);
239 
240     vdencPictureStatesSize =
241         m_vdencInterfaceNew->MHW_GETSIZE_F(VDENC_PIPE_MODE_SELECT)() +
242         m_vdencInterfaceNew->MHW_GETSIZE_F(VDENC_SRC_SURFACE_STATE)() +
243         m_vdencInterfaceNew->MHW_GETSIZE_F(VDENC_REF_SURFACE_STATE)() +
244         m_vdencInterfaceNew->MHW_GETSIZE_F(VDENC_DS_REF_SURFACE_STATE)() +
245         m_vdencInterfaceNew->MHW_GETSIZE_F(VDENC_PIPE_BUF_ADDR_STATE)() +
246         m_vdencInterfaceNew->MHW_GETSIZE_F(VDENC_WALKER_STATE)() +
247         m_vdencInterfaceNew->MHW_GETSIZE_F(VD_PIPELINE_FLUSH)() +
248         m_miItf->MHW_GETSIZE_F(MI_FLUSH_DW)() +
249         m_miItf->MHW_GETSIZE_F(MI_BATCH_BUFFER_START)();
250 
251     vdencPicturePatchListSize =
252         PATCH_LIST_COMMAND(mhw::mi::Itf::MI_FLUSH_DW_CMD) +
253         PATCH_LIST_COMMAND(mhw::mi::Itf::MI_BATCH_BUFFER_START_CMD) +
254         PATCH_LIST_COMMAND(mhw::vdbox::vdenc::Itf::VDENC_PIPE_BUF_ADDR_STATE_CMD);
255 
256     return MOS_STATUS_SUCCESS;
257 }
258 
DumpOutput()259 MOS_STATUS Vp9VdencPkt::DumpOutput()
260 {
261     ENCODE_FUNC_CALL();
262 
263 #if USE_CODECHAL_DEBUG_TOOL
264     // Dump output (resource, information, etc) after command submission
265     CodechalDebugInterface *debugInterface = m_pipeline->GetDebugInterface();
266     ENCODE_CHK_NULL_RETURN(debugInterface);
267 
268     CODEC_REF_LIST currRefList = *((CODEC_REF_LIST *)m_basicFeature->m_ref.GetCurrRefList());
269 
270     std::stringstream pipeIdxStrStream;
271     pipeIdxStrStream << "_" << (int)m_pipeline->GetCurrentPipe();
272 
273     std::string bufferPassName = GetPacketName();
274     bufferPassName += pipeIdxStrStream.str() + "_output";
275 
276     std::string surfacePassName = "PASS" + std::to_string((uint32_t)m_pipeline->GetCurrentPass());
277     surfacePassName += pipeIdxStrStream.str() + "_output";
278 
279     if (m_basicFeature->m_ref.DysRefFrameFlags() == DYS_REF_NONE && m_resVdencPakObjCmdStreamOutBuffer != nullptr)
280     {
281         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
282             m_resVdencPakObjCmdStreamOutBuffer,
283             CodechalDbgAttr::attrPakObjStreamout,
284             bufferPassName.data(),
285             m_basicFeature->m_mbCodeSize + 8 * CODECHAL_CACHELINE_SIZE,
286             0,
287             CODECHAL_NUM_MEDIA_STATES));
288     }
289 
290     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
291         &currRefList.resBitstreamBuffer,
292         CodechalDbgAttr::attrBitstream,
293         bufferPassName.data(),
294         m_basicFeature->m_bitstreamSize,
295         0,
296         CODECHAL_NUM_MEDIA_STATES));
297 
298     PMOS_RESOURCE frameStatStreamOutBuffer = m_basicFeature->m_recycleBuf->GetBuffer(FrameStatStreamOutBuffer, 0);
299     ENCODE_CHK_NULL_RETURN(frameStatStreamOutBuffer);
300     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
301         frameStatStreamOutBuffer,
302         CodechalDbgAttr::attrFrameState,
303         bufferPassName.data(),
304         frameStatStreamOutBuffer->iSize,
305         0,
306         CODECHAL_NUM_MEDIA_STATES));
307 
308     MOS_SURFACE *ds4xSurface = m_basicFeature->m_trackedBuf->GetSurface(
309         BufferType::ds4xSurface, currRefList.ucScalingIdx);
310     if (ds4xSurface != nullptr)
311     {
312         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
313             ds4xSurface,
314             CodechalDbgAttr::attrReconstructedSurface,
315             (surfacePassName + "_4xScaledSurf").data()));
316     }
317 
318     MOS_SURFACE *ds8xSurface = m_basicFeature->m_trackedBuf->GetSurface(
319         BufferType::ds8xSurface, currRefList.ucScalingIdx);
320     if (ds8xSurface != nullptr)
321     {
322         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
323             ds8xSurface,
324             CodechalDbgAttr::attrReconstructedSurface,
325             (surfacePassName + "_8xScaledSurf").data()));
326     }
327 
328     MOS_RESOURCE *mbCodedBuffer = m_basicFeature->m_trackedBuf->GetBuffer(
329         BufferType::mbCodedBuffer, currRefList.ucScalingIdx);
330     if (mbCodedBuffer != nullptr)
331     {
332         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
333             mbCodedBuffer,
334             CodechalDbgAttr::attrVdencOutput,
335             (bufferPassName + "_MbCode").data(),
336             m_basicFeature->m_mbCodeSize + 8 * CODECHAL_CACHELINE_SIZE,
337             0,
338             CODECHAL_NUM_MEDIA_STATES));
339     }
340 
341     auto          streamInBufferSize = (MOS_ALIGN_CEIL(m_basicFeature->m_frameWidth, 64) / 32) * (MOS_ALIGN_CEIL(m_basicFeature->m_frameHeight, 64) / 32) * CODECHAL_CACHELINE_SIZE;
342     PMOS_RESOURCE streamInBuffer     = m_basicFeature->m_recycleBuf->GetBuffer(RecycleResId::StreamInBuffer, m_basicFeature->m_frameNum);
343     if (streamInBuffer != nullptr)
344     {
345         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
346             streamInBuffer,
347             CodechalDbgAttr::attrStreamIn,
348             bufferPassName.data(),
349             streamInBufferSize,
350             0,
351             CODECHAL_NUM_MEDIA_STATES));
352     }
353 
354     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBltOutput(
355         &currRefList.sRefReconBuffer,
356         CodechalDbgAttr::attrDecodeBltOutput));
357     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
358         &currRefList.sRefReconBuffer,
359         CodechalDbgAttr::attrReconstructedSurface,
360         (surfacePassName + "_ReconSurf").data()));
361 
362     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBltOutput(
363         &currRefList.sRefRawBuffer,
364         CodechalDbgAttr::attrDecodeBltOutput));
365     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
366         &currRefList.sRefRawBuffer,
367         CodechalDbgAttr::attrEncodeRawInputSurface,
368         (surfacePassName + "_SrcSurf").data()));
369 #endif
370 
371     return MOS_STATUS_SUCCESS;
372 }
373 
GetHxxPrimitiveCommandSize()374 MOS_STATUS Vp9VdencPkt::GetHxxPrimitiveCommandSize()
375 {
376     ENCODE_FUNC_CALL();
377 
378     ENCODE_CHK_NULL_RETURN(m_hwInterface);
379     ENCODE_CHK_NULL_RETURN(m_pipeline);
380 
381     uint32_t hcpCommandsSize = 0;
382     uint32_t hcpPatchListSize = 0;
383     if (m_pipeline->IsSingleTaskPhaseSupported())
384     {
385         hcpCommandsSize +=
386             m_hcpInterfaceNew->MHW_GETSIZE_F(HCP_VP9_SEGMENT_STATE)() * 8 +
387             m_hcpInterfaceNew->MHW_GETSIZE_F(HCP_VP9_PIC_STATE)() +
388             m_hcpInterfaceNew->MHW_GETSIZE_F(HCP_BSD_OBJECT)() +
389             m_miItf->MHW_GETSIZE_F(MI_BATCH_BUFFER_END)();
390 
391         hcpPatchListSize =
392             mhw::vdbox::hcp::Itf::HCP_VP9_SEGMENT_STATE_CMD_NUMBER_OF_ADDRESSES * 8 +
393             mhw::vdbox::hcp::Itf::HCP_VP9_PIC_STATE_CMD_NUMBER_OF_ADDRESSES +
394             mhw::vdbox::hcp::Itf::HCP_BSD_OBJECT_CMD_NUMBER_OF_ADDRESSES;
395     }
396 
397     uint32_t cpCmdsize = 0;
398     uint32_t cpPatchListSize = 0;
399     if (m_hwInterface->GetCpInterface())
400     {
401         m_hwInterface->GetCpInterface()->GetCpSliceLevelCmdSize(cpCmdsize, cpPatchListSize);
402     }
403 
404     m_defaultSliceStatesSize = hcpCommandsSize + (uint32_t)cpCmdsize;
405     m_defaultSlicePatchListSize = hcpPatchListSize + (uint32_t)cpPatchListSize;
406 
407     return MOS_STATUS_SUCCESS;
408 }
409 
CalculateCommandBufferSize()410 uint32_t Vp9VdencPkt::CalculateCommandBufferSize()
411 {
412     ENCODE_FUNC_CALL();
413     uint32_t commandBufferSize = 0;
414 
415     commandBufferSize = m_pictureStatesSize + (m_sliceStatesSize * m_basicFeature->m_numSlices);
416     if (m_pipeline->IsSingleTaskPhaseSupported())
417     {
418         commandBufferSize *= m_pipeline->GetPassNum();
419     }
420 
421     // 4K align since allocation is in chunks of 4K bytes
422     commandBufferSize = MOS_ALIGN_CEIL(commandBufferSize, CODECHAL_PAGE_SIZE);
423 
424     return commandBufferSize;
425 }
426 
CalculatePatchListSize()427 uint32_t Vp9VdencPkt::CalculatePatchListSize()
428 {
429     ENCODE_FUNC_CALL();
430     uint32_t requestedPatchListSize = 0;
431 
432     if (m_usePatchList)
433     {
434         requestedPatchListSize = m_picturePatchListSize + (m_slicePatchListSize * m_basicFeature->m_numSlices);
435         if (m_pipeline->IsSingleTaskPhaseSupported())
436         {
437             requestedPatchListSize *= m_pipeline->GetPassNum();
438         }
439 
440         // Multi pipes are sharing one patchlist
441         requestedPatchListSize *= m_pipeline->GetPipeNum();
442     }
443 
444     return requestedPatchListSize;
445 }
446 
AllocateResources()447 MOS_STATUS Vp9VdencPkt::AllocateResources()
448 {
449     ENCODE_FUNC_CALL();
450 
451     ENCODE_CHK_NULL_RETURN(m_allocator);
452 
453     MOS_RESOURCE *allocatedBuffer  = nullptr;
454     uint32_t      maxPicWidthInSb  = MOS_ROUNDUP_DIVIDE(m_basicFeature->m_frameWidth, CODEC_VP9_SUPER_BLOCK_WIDTH);
455     uint32_t      maxPicHeightInSb = MOS_ROUNDUP_DIVIDE(m_basicFeature->m_frameHeight, CODEC_VP9_SUPER_BLOCK_HEIGHT);
456     uint32_t      maxPicSizeInSb   = maxPicWidthInSb * maxPicHeightInSb;
457 
458     // Initiate allocation parameters and lock flags
459     MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
460     MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
461     allocParamsForBufferLinear.Type     = MOS_GFXRES_BUFFER;
462     allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
463     allocParamsForBufferLinear.Format   = Format_Buffer;
464 
465     MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D;
466     MOS_ZeroMemory(&allocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS));
467     allocParamsForBuffer2D.Type     = MOS_GFXRES_2D;
468     allocParamsForBuffer2D.TileType = MOS_TILE_LINEAR;
469     allocParamsForBuffer2D.Format   = Format_Buffer_2D;
470 
471     MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferNV12;
472     MOS_ZeroMemory(&allocParamsForBufferNV12, sizeof(MOS_ALLOC_GFXRES_PARAMS));
473     allocParamsForBufferNV12.Type     = MOS_GFXRES_2D;
474     allocParamsForBufferNV12.TileType = MOS_TILE_Y;
475     allocParamsForBufferNV12.Format   = Format_NV12;
476 
477     if (m_basicFeature->m_encEnabled)
478     {
479         if (m_basicFeature->m_hmeSupported)
480         {
481             MOS_ZeroMemory(&m_4xMeMvDataBuffer, sizeof(MOS_SURFACE));
482             m_4xMeMvDataBuffer.TileType      = MOS_TILE_LINEAR;
483             m_4xMeMvDataBuffer.bArraySpacing = true;
484             m_4xMeMvDataBuffer.Format        = Format_Buffer_2D;
485             m_4xMeMvDataBuffer.dwWidth       = m_basicFeature->m_downscaledWidthInMb4x * 32;
486             m_4xMeMvDataBuffer.dwHeight      = m_basicFeature->m_downscaledHeightInMb4x * 4 * 10;
487             m_4xMeMvDataBuffer.dwPitch       = MOS_ALIGN_CEIL(m_4xMeMvDataBuffer.dwWidth, 128);
488 
489             allocParamsForBuffer2D.dwWidth  = m_4xMeMvDataBuffer.dwWidth;
490             allocParamsForBuffer2D.dwHeight = m_4xMeMvDataBuffer.dwHeight;
491             allocParamsForBuffer2D.pBufName = "4xME MV Data Buffer";
492             allocParamsForBuffer2D.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE;
493             allocatedBuffer                 = m_allocator->AllocateResource(allocParamsForBuffer2D, true);
494             ENCODE_CHK_NULL_RETURN(allocatedBuffer);
495             m_4xMeMvDataBuffer.OsResource = *allocatedBuffer;
496 
497             MOS_ZeroMemory(&m_4xMeDistortionBuffer, sizeof(MOS_SURFACE));
498             m_4xMeDistortionBuffer.TileType      = MOS_TILE_LINEAR;
499             m_4xMeDistortionBuffer.bArraySpacing = true;
500             m_4xMeDistortionBuffer.Format        = Format_Buffer_2D;
501             m_4xMeDistortionBuffer.dwWidth       = m_basicFeature->m_downscaledWidthInMb4x * 8;
502             m_4xMeDistortionBuffer.dwHeight      = m_basicFeature->m_downscaledHeightInMb4x * 4 * 10;
503             m_4xMeDistortionBuffer.dwPitch       = MOS_ALIGN_CEIL(m_4xMeDistortionBuffer.dwWidth, 128);
504 
505             allocParamsForBuffer2D.dwWidth  = m_4xMeDistortionBuffer.dwWidth;
506             allocParamsForBuffer2D.dwHeight = m_4xMeDistortionBuffer.dwHeight;
507             allocParamsForBuffer2D.pBufName = "4xME Distortion Buffer";
508             allocatedBuffer                 = m_allocator->AllocateResource(allocParamsForBuffer2D, true);
509             ENCODE_CHK_NULL_RETURN(allocatedBuffer);
510             m_4xMeDistortionBuffer.OsResource = *allocatedBuffer;
511         }
512 
513         if (m_basicFeature->m_16xMeSupported)
514         {
515             MOS_ZeroMemory(&m_16xMeMvDataBuffer, sizeof(MOS_SURFACE));
516             m_16xMeMvDataBuffer.TileType      = MOS_TILE_LINEAR;
517             m_16xMeMvDataBuffer.bArraySpacing = true;
518             m_16xMeMvDataBuffer.Format        = Format_Buffer_2D;
519             m_16xMeMvDataBuffer.dwWidth       = MOS_ALIGN_CEIL((m_basicFeature->m_downscaledWidthInMb16x * 32), 64);
520             m_16xMeMvDataBuffer.dwHeight      = m_basicFeature->m_downscaledHeightInMb16x * 4 * 10;
521             m_16xMeMvDataBuffer.dwPitch       = MOS_ALIGN_CEIL(m_16xMeMvDataBuffer.dwWidth, 128);
522 
523             allocParamsForBuffer2D.dwWidth  = m_16xMeMvDataBuffer.dwWidth;
524             allocParamsForBuffer2D.dwHeight = m_16xMeMvDataBuffer.dwHeight;
525             allocParamsForBuffer2D.pBufName = "16xME MV Data Buffer";
526             allocParamsForBuffer2D.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE;
527             allocatedBuffer                 = m_allocator->AllocateResource(allocParamsForBuffer2D, true);
528             ENCODE_CHK_NULL_RETURN(allocatedBuffer);
529             m_16xMeMvDataBuffer.OsResource = *allocatedBuffer;
530         }
531 
532         // Intermediate surface to be used by the P kernel to help reduce number of SIC calls
533         MOS_ZeroMemory(&m_output16X16InterModes, sizeof(MOS_SURFACE));
534         m_output16X16InterModes.TileType      = MOS_TILE_LINEAR;
535         m_output16X16InterModes.bArraySpacing = true;
536         m_output16X16InterModes.Format        = Format_Buffer_2D;
537         m_output16X16InterModes.dwWidth       = 16 * m_basicFeature->m_picWidthInMb;
538         m_output16X16InterModes.dwHeight      = 8 * m_basicFeature->m_picHeightInMb;
539         m_output16X16InterModes.dwPitch       = MOS_ALIGN_CEIL(m_output16X16InterModes.dwWidth, 64);
540 
541         allocParamsForBuffer2D.dwWidth  = m_output16X16InterModes.dwWidth;
542         allocParamsForBuffer2D.dwHeight = m_output16X16InterModes.dwHeight;
543         allocParamsForBuffer2D.pBufName = "Intermediate surface";
544         allocParamsForBuffer2D.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE;
545         allocatedBuffer                 = m_allocator->AllocateResource(allocParamsForBuffer2D, true);
546         ENCODE_CHK_NULL_RETURN(allocatedBuffer);
547         m_output16X16InterModes.OsResource = *allocatedBuffer;
548     }
549 
550     // VDENC intra row store scratch buffer
551     allocParamsForBufferLinear.dwBytes  = m_basicFeature->m_picWidthInMb * CODECHAL_CACHELINE_SIZE;
552     allocParamsForBufferLinear.pBufName = "VDENC Intra Row Store Scratch Buffer";
553     allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE;
554     allocatedBuffer                     = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
555     ENCODE_CHK_NULL_RETURN(allocatedBuffer);
556     m_resVdencIntraRowStoreScratchBuffer = *allocatedBuffer;
557 
558     // HVC tile row store buffer
559     allocParamsForBufferLinear.dwBytes  = CODECHAL_CACHELINE_SIZE * maxPicWidthInSb;
560     allocParamsForBufferLinear.pBufName = "HvcTileRowStoreBuffer";
561     allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ;
562     allocatedBuffer                     = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
563     ENCODE_CHK_NULL_RETURN(allocatedBuffer);
564     m_resHvcTileRowStoreBuffer = *allocatedBuffer;
565 
566     // This stream out/stream in buffer may need to be a separate buffer on HW, in which case
567     // we'll create 2 and ping-pong back and forth pre-frame. For now, though, on simulation/SW,
568     // they can be the same buffer.
569     allocParamsForBufferLinear.dwBytes  = CODECHAL_CACHELINE_SIZE * maxPicSizeInSb;
570     allocParamsForBufferLinear.pBufName = "VDENC Segment Map Stream Out";
571     allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ;
572     allocatedBuffer                     = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
573     ENCODE_CHK_NULL_RETURN(allocatedBuffer);
574     m_resVdencSegmentMapStreamOut = *allocatedBuffer;
575 
576     // Allocate SSE source pixel row store buffer
577     m_basicFeature->m_sizeOfSseSrcPixelRowStoreBufferPerLcu = ((maxPicWidthInSb + 2) << 5) * CODECHAL_CACHELINE_SIZE;
578 
579     uint32_t size                       = m_basicFeature->m_sizeOfSseSrcPixelRowStoreBufferPerLcu * m_basicFeature->m_maxTileNumber;
580     allocParamsForBufferLinear.dwBytes  = size;
581     allocParamsForBufferLinear.pBufName = "SseSrcPixelRowStoreBuffer";
582     allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE;
583     allocatedBuffer                     = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
584 
585     ENCODE_CHK_NULL_RETURN(allocatedBuffer);
586     m_resSseSrcPixelRowStoreBuffer = *allocatedBuffer;
587 
588     // VDenc stream-in data buffer
589     allocParamsForBufferLinear.dwBytes = (MOS_ALIGN_CEIL(m_basicFeature->m_frameWidth, 64) / 32) *
590                                          (MOS_ALIGN_CEIL(m_basicFeature->m_frameHeight, 64) / 32) * CODECHAL_CACHELINE_SIZE;
591     allocParamsForBufferLinear.pBufName = "VDEnc StreamIn Data Buffer";
592     allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE;
593     m_basicFeature->m_recycleBuf->RegisterResource(RecycleResId::StreamInBuffer, allocParamsForBufferLinear);
594 
595     return MOS_STATUS_SUCCESS;
596 }
597 
FreeResources()598 MOS_STATUS Vp9VdencPkt::FreeResources()
599 {
600     ENCODE_FUNC_CALL();
601     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
602 
603     return eStatus;
604 }
605 
ValidateVdboxIdx(const MHW_VDBOX_NODE_IND & vdboxIndex)606 MOS_STATUS Vp9VdencPkt::ValidateVdboxIdx(const MHW_VDBOX_NODE_IND &vdboxIndex)
607 {
608     ENCODE_FUNC_CALL();
609     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
610 
611     if (vdboxIndex > m_hwInterface->GetMaxVdboxIndex())
612     {
613         // ENCODE_ASSERTMESSAGE("ERROR = vdbox index exceed the maximum");
614         eStatus = MOS_STATUS_INVALID_PARAMETER;
615     }
616 
617     return eStatus;
618 }
619 
SetPerfTag(uint16_t type,uint16_t mode,uint16_t picCodingType)620 void Vp9VdencPkt::SetPerfTag(uint16_t type, uint16_t mode, uint16_t picCodingType)
621 {
622     ENCODE_FUNC_CALL();
623 
624     PerfTagSetting perfTag;
625     perfTag.Value             = 0;
626     perfTag.Mode              = mode & CODECHAL_ENCODE_MODE_BIT_MASK;
627     perfTag.CallType          = type;
628     perfTag.PictureCodingType = picCodingType > 3 ? 0 : picCodingType;
629     m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
630     m_osInterface->pfnIncPerfBufferID(m_osInterface);
631 }
632 
AddForceWakeup(MOS_COMMAND_BUFFER & cmdBuffer)633 MOS_STATUS Vp9VdencPkt::AddForceWakeup(MOS_COMMAND_BUFFER &cmdBuffer)
634 {
635     ENCODE_FUNC_CALL();
636 
637     ENCODE_CHK_NULL_RETURN(m_miItf);
638 
639     auto &forceWakeupParams = m_miItf->MHW_GETPAR_F(MI_FORCE_WAKEUP)();
640 
641     forceWakeupParams                           = {};
642     forceWakeupParams.bMFXPowerWellControl      = true;
643     forceWakeupParams.bMFXPowerWellControlMask  = true;
644     forceWakeupParams.bHEVCPowerWellControl     = true;
645     forceWakeupParams.bHEVCPowerWellControlMask = true;
646 
647     ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FORCE_WAKEUP)(&cmdBuffer));
648 
649     return MOS_STATUS_SUCCESS;
650 }
651 
SendPrologCmds(MOS_COMMAND_BUFFER & cmdBuffer)652 MOS_STATUS Vp9VdencPkt::SendPrologCmds(MOS_COMMAND_BUFFER &cmdBuffer)
653 {
654     ENCODE_FUNC_CALL();
655 
656 #ifdef _MMC_SUPPORTED
657     ENCODE_CHK_NULL_RETURN(m_mmcState);
658     ENCODE_CHK_STATUS_RETURN(m_mmcState->SendPrologCmd(&cmdBuffer, false));
659 #endif
660 
661     MHW_GENERIC_PROLOG_PARAMS genericPrologParams;
662     MOS_ZeroMemory(&genericPrologParams, sizeof(genericPrologParams));
663     genericPrologParams.pOsInterface     = m_osInterface;
664     genericPrologParams.pvMiInterface    = nullptr;
665     genericPrologParams.bMmcEnabled      = m_mmcState ? m_mmcState->IsMmcEnabled() : false;
666     genericPrologParams.dwStoreDataValue = m_basicFeature->m_frameNum;
667     ENCODE_CHK_STATUS_RETURN(Mhw_SendGenericPrologCmdNext(&cmdBuffer, &genericPrologParams, m_miItf));
668 
669     return MOS_STATUS_SUCCESS;
670 }
671 
SetRowstoreCachingOffsets()672 MOS_STATUS Vp9VdencPkt::SetRowstoreCachingOffsets()
673 {
674     ENCODE_FUNC_CALL();
675 
676     MHW_VDBOX_ROWSTORE_PARAMS rowStoreParams;
677     rowStoreParams.Mode             = m_basicFeature->m_mode;
678     rowStoreParams.dwPicWidth       = m_basicFeature->m_frameWidth;
679     rowStoreParams.ucChromaFormat   = m_basicFeature->m_chromaFormat;
680     rowStoreParams.ucBitDepthMinus8 = (m_basicFeature->m_bitDepth - 8);  // 0(8bit) -> 0, 1(10bit)->2, 2(12bit)->4
681     if (m_hcpInterfaceNew->IsRowStoreCachingSupported())
682     {
683         ENCODE_CHK_STATUS_RETURN(m_hwInterface->SetRowstoreCachingOffsets(&rowStoreParams));
684     }
685 
686     if (m_hcpInterfaceNew->IsRowStoreCachingSupported())
687     {
688         hcp::HcpVdboxRowStorePar rowstoreParamsHCP = {};
689         rowstoreParamsHCP.Mode             = m_basicFeature->m_mode;
690         rowstoreParamsHCP.dwPicWidth       = m_basicFeature->m_frameWidth;
691         rowstoreParamsHCP.ucChromaFormat   = m_basicFeature->m_chromaFormat;
692         rowstoreParamsHCP.ucBitDepthMinus8 = (m_basicFeature->m_bitDepth - 8);  // 0(8bit) -> 0, 1(10bit)->2, 2(12bit)->4
693         ENCODE_CHK_STATUS_RETURN(m_hcpInterfaceNew->SetRowstoreCachingOffsets(rowstoreParamsHCP));
694     }
695 
696     if (m_vdencInterfaceNew)
697     {
698         mhw::vdbox::vdenc::RowStorePar par = {};
699 
700         par.mode = mhw::vdbox::vdenc::RowStorePar::VP9;
701         par.bitDepth = mhw::vdbox::vdenc::RowStorePar::DEPTH_8;
702         if (rowStoreParams.ucBitDepthMinus8 == 1 || rowStoreParams.ucBitDepthMinus8 == 2)
703         {
704             par.bitDepth = mhw::vdbox::vdenc::RowStorePar::DEPTH_10;
705         }
706         else if (rowStoreParams.ucBitDepthMinus8 > 2)
707         {
708             par.bitDepth = mhw::vdbox::vdenc::RowStorePar::DEPTH_12;
709         }
710         par.frameWidth = rowStoreParams.dwPicWidth;
711         switch (rowStoreParams.ucChromaFormat)
712         {
713         case HCP_CHROMA_FORMAT_MONOCHROME:
714             par.format = mhw ::vdbox::vdenc::RowStorePar::MONOCHROME;
715             break;
716         case HCP_CHROMA_FORMAT_YUV420:
717             par.format = mhw ::vdbox::vdenc::RowStorePar::YUV420;
718             break;
719         case HCP_CHROMA_FORMAT_YUV422:
720             par.format = mhw ::vdbox::vdenc::RowStorePar::YUV422;
721             break;
722         case HCP_CHROMA_FORMAT_YUV444:
723             par.format = mhw ::vdbox::vdenc::RowStorePar::YUV444;
724             break;
725         }
726 
727         ENCODE_CHK_STATUS_RETURN(m_vdencInterfaceNew->SetRowstoreCachingOffsets(par));
728     }
729 
730     return MOS_STATUS_SUCCESS;
731 }
732 
AddHcpPipeBufAddrCmd(MOS_COMMAND_BUFFER & cmdBuffer)733 MOS_STATUS Vp9VdencPkt::AddHcpPipeBufAddrCmd(MOS_COMMAND_BUFFER &cmdBuffer)
734 {
735     if (m_basicFeature->m_ref.DysRefFrameFlags() == DYS_REF_NONE)
736     {
737         m_resVdencPakObjCmdStreamOutBuffer = m_basicFeature->m_resMbCodeBuffer;
738     }
739 
740     RUN_FEATURE_INTERFACE_RETURN(Vp9EncodeHpu, Vp9FeatureIDs::vp9HpuFeature, SetIsLastPass, m_pipeline->IsLastPass());
741     SETPAR_AND_ADDCMD(HCP_PIPE_BUF_ADDR_STATE, m_hcpInterfaceNew, &cmdBuffer);
742 
743     return MOS_STATUS_SUCCESS;
744 }
745 
SetHcpSurfaceMMCState()746 MOS_STATUS Vp9VdencPkt::SetHcpSurfaceMMCState()
747 {
748 #ifdef _MMC_SUPPORTED
749     for (uint8_t i = 0; i <= CODECHAL_HCP_ALTREF_SURFACE_ID; ++i)
750     {
751         SetSurfaceMmcState(&m_surfacesParams[i]);
752     }
753     //Get each reference surface state and be recorded by skipMask if current surface state is mmc disabled
754     //In VP9 mode, Bit 8is (here is bit0 in skipMask ) for Previous Reference;
755     //Bit 9is (here is bit1 in skipMask ) for Golden Reference and Bit 10is (here is bit2 in skipMask ) for Alterante Reference;
756     //Bits11-15are unused and should be programmed to 0 (skipped)
757     uint8_t skipMask = 0xf8;
758     for (uint8_t i = CODECHAL_HCP_LAST_SURFACE_ID; i <= CODECHAL_HCP_ALTREF_SURFACE_ID; i++)
759     {
760         if (m_surfacesParams[i].mmcState == MOS_MEMCOMP_DISABLED)
761         {
762             skipMask |= (1 << (i - 2));
763         }
764     }
765     ENCODE_NORMALMESSAGE("MMC skip mask is %d\n", skipMask);
766     for (uint8_t i = CODECHAL_HCP_LAST_SURFACE_ID; i <= CODECHAL_HCP_ALTREF_SURFACE_ID; i++)
767     {
768         //Set each ref surface state as MOS_MEMCOMP_MC to satisfy MmcEnable in AddHcpSurfaceCmd
769         //Because each ref surface state should be programmed as the same
770         //The actual mmc state is recorded by skipMask and set each ref surface too
771         m_surfacesParams[i].mmcState = MOS_MEMCOMP_MC;
772         m_surfacesParams[i].mmcSkipMask = skipMask;
773     }
774 #endif  // _MMC_SUPPORTED
775     return MOS_STATUS_SUCCESS;
776 }
777 
fill_pad_with_value(PMOS_SURFACE psSurface,uint32_t real_height,uint32_t aligned_height)778 void Vp9VdencPkt::fill_pad_with_value(PMOS_SURFACE psSurface, uint32_t real_height, uint32_t aligned_height)
779 {
780     ENCODE_CHK_NULL_NO_STATUS_RETURN(psSurface);
781 
782     // unaligned surfaces only
783     if (aligned_height <= real_height || aligned_height > psSurface->dwHeight)
784     {
785         return;
786     }
787 
788     // avoid DYS frames cases
789     if (m_basicFeature->m_ref.DysRefFrameFlags() != DYS_REF_NONE && m_basicFeature->m_dysVdencMultiPassEnabled)
790     {
791         return;
792     }
793 
794     if (psSurface->OsResource.TileType == MOS_TILE_INVALID)
795     {
796         return;
797     }
798 
799     if (psSurface->Format == Format_NV12 || psSurface->Format == Format_P010)
800     {
801         uint32_t pitch         = psSurface->dwPitch;
802         uint32_t UVPlaneOffset = psSurface->UPlaneOffset.iSurfaceOffset;
803         uint32_t YPlaneOffset  = psSurface->dwOffset;
804         uint32_t pad_rows = aligned_height - real_height;
805         uint32_t y_plane_size   = pitch * real_height;
806         uint32_t uv_plane_size   = pitch * real_height / 2;
807 
808         MOS_LOCK_PARAMS lockFlags;
809         MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
810         lockFlags.WriteOnly = 1;
811 
812         // padding for the linear format buffer.
813         if (psSurface->OsResource.TileType == MOS_TILE_LINEAR)
814         {
815             uint8_t *src_data   = (uint8_t *)m_osInterface->pfnLockResource(m_osInterface, &(psSurface->OsResource), &lockFlags);
816 
817             if (!src_data)
818                 return;
819 
820             uint8_t *src_data_y     = src_data + YPlaneOffset;
821             uint8_t *src_data_y_end = src_data_y + y_plane_size;
822             for (uint32_t i = 0; i < pad_rows; i++)
823             {
824                 MOS_SecureMemcpy(src_data_y_end + i * pitch, pitch, src_data_y_end - pitch, pitch);
825             }
826 
827             uint8_t *src_data_uv     = src_data + UVPlaneOffset;
828             uint8_t *src_data_uv_end = src_data_uv + uv_plane_size;
829             for (uint32_t i = 0; i < pad_rows / 2; i++)
830             {
831                 MOS_SecureMemcpy(src_data_uv_end + i * pitch, pitch, src_data_uv_end - pitch, pitch);
832             }
833 
834             m_osInterface->pfnUnlockResource(m_osInterface, &(psSurface->OsResource));
835         }
836         else
837         {
838             // we don't copy out the whole tiled buffer to linear and padding on the tiled buffer directly.
839             lockFlags.TiledAsTiled = 1;
840 
841             uint8_t *src_data   = (uint8_t *)m_osInterface->pfnLockResource(m_osInterface, &(psSurface->OsResource), &lockFlags);
842             if (!src_data)
843                 return;
844 
845             uint8_t* padding_data = (uint8_t *)MOS_AllocMemory(pitch * pad_rows);
846 
847             // Copy last Y row data to linear padding data.
848             GMM_RES_COPY_BLT    gmmResCopyBlt  = {0};
849             gmmResCopyBlt.Gpu.pData      = src_data;
850             gmmResCopyBlt.Gpu.OffsetX    = 0;
851             gmmResCopyBlt.Gpu.OffsetY    = (YPlaneOffset + y_plane_size - pitch) / pitch;
852             gmmResCopyBlt.Sys.pData      = padding_data;
853             gmmResCopyBlt.Sys.RowPitch   = pitch;
854             gmmResCopyBlt.Sys.BufferSize = pitch * pad_rows;
855             gmmResCopyBlt.Sys.SlicePitch = pitch;
856             gmmResCopyBlt.Blt.Slices     = 1;
857             gmmResCopyBlt.Blt.Upload     = false;
858             gmmResCopyBlt.Blt.Width      = psSurface->dwWidth;
859             gmmResCopyBlt.Blt.Height     = 1;
860             psSurface->OsResource.pGmmResInfo->CpuBlt(&gmmResCopyBlt);
861             // Fill the remain padding lines with last Y row data.
862             for (uint32_t i = 1; i < pad_rows; i++)
863             {
864                 MOS_SecureMemcpy(padding_data + i * pitch, pitch, padding_data, pitch);
865             }
866             // Filling the padding for Y.
867             gmmResCopyBlt.Gpu.pData      = src_data;
868             gmmResCopyBlt.Gpu.OffsetX    = 0;
869             gmmResCopyBlt.Gpu.OffsetY    = (YPlaneOffset + y_plane_size) / pitch;
870             gmmResCopyBlt.Sys.pData      = padding_data;
871             gmmResCopyBlt.Sys.RowPitch   = pitch;
872             gmmResCopyBlt.Sys.BufferSize = pitch * pad_rows;
873             gmmResCopyBlt.Sys.SlicePitch = pitch;
874             gmmResCopyBlt.Blt.Slices     = 1;
875             gmmResCopyBlt.Blt.Upload     = true;
876             gmmResCopyBlt.Blt.Width      = psSurface->dwWidth;
877             gmmResCopyBlt.Blt.Height     = pad_rows;
878             psSurface->OsResource.pGmmResInfo->CpuBlt(&gmmResCopyBlt);
879 
880             // Copy last UV row data to linear padding data.
881             gmmResCopyBlt.Gpu.pData      = src_data;
882             gmmResCopyBlt.Gpu.OffsetX    = 0;
883             gmmResCopyBlt.Gpu.OffsetY    = (UVPlaneOffset + uv_plane_size - pitch) / pitch;
884             gmmResCopyBlt.Sys.pData      = padding_data;
885             gmmResCopyBlt.Sys.RowPitch   = pitch;
886             gmmResCopyBlt.Sys.BufferSize = pitch * pad_rows / 2;
887             gmmResCopyBlt.Sys.SlicePitch = pitch;
888             gmmResCopyBlt.Blt.Slices     = 1;
889             gmmResCopyBlt.Blt.Upload     = false;
890             gmmResCopyBlt.Blt.Width      = psSurface->dwWidth;
891             gmmResCopyBlt.Blt.Height     = 1;
892             psSurface->OsResource.pGmmResInfo->CpuBlt(&gmmResCopyBlt);
893             // Fill the remain padding lines with last UV row data.
894             for (uint32_t i = 1; i < pad_rows / 2; i++)
895             {
896                 MOS_SecureMemcpy(padding_data + i * pitch, pitch, padding_data, pitch);
897             }
898             // Filling the padding for UV.
899             gmmResCopyBlt.Gpu.pData      = src_data;
900             gmmResCopyBlt.Gpu.OffsetX    = 0;
901             gmmResCopyBlt.Gpu.OffsetY    = (UVPlaneOffset + uv_plane_size) / pitch;
902             gmmResCopyBlt.Sys.pData      = padding_data;
903             gmmResCopyBlt.Sys.RowPitch   = pitch;
904             gmmResCopyBlt.Sys.BufferSize = pitch * pad_rows / 2;
905             gmmResCopyBlt.Sys.SlicePitch = pitch;
906             gmmResCopyBlt.Blt.Slices     = 1;
907             gmmResCopyBlt.Blt.Upload     = true;
908             gmmResCopyBlt.Blt.Width      = psSurface->dwWidth;
909             gmmResCopyBlt.Blt.Height     = pad_rows / 2;
910             psSurface->OsResource.pGmmResInfo->CpuBlt(&gmmResCopyBlt);
911 
912             MOS_FreeMemory(padding_data);
913             padding_data = nullptr;
914             m_osInterface->pfnUnlockResource(m_osInterface, &(psSurface->OsResource));
915         }
916     }
917 }
918 
SetHcpSurfacesParams(MHW_VDBOX_SURFACE_PARAMS * surfacesParams)919 MOS_STATUS Vp9VdencPkt::SetHcpSurfacesParams(MHW_VDBOX_SURFACE_PARAMS *surfacesParams)
920 {
921     ENCODE_FUNC_CALL();
922 
923     for (uint8_t i = 0; i <= CODECHAL_HCP_ALTREF_SURFACE_ID; ++i)
924     {
925         MOS_ZeroMemory(&surfacesParams[i], sizeof(surfacesParams[i]));
926         surfacesParams[i].Mode             = m_basicFeature->m_mode;
927         surfacesParams[i].ucSurfaceStateId = i;
928         surfacesParams[i].ChromaType       = m_basicFeature->m_outputChromaFormat;
929         surfacesParams[i].bSrc8Pak10Mode   = (m_vp9SeqParams->SeqFlags.fields.EncodedBitDepth) && (!m_vp9SeqParams->SeqFlags.fields.SourceBitDepth);
930 
931         switch (m_vp9SeqParams->SeqFlags.fields.EncodedBitDepth)
932         {
933         case VP9_ENCODED_BIT_DEPTH_10: {
934             surfacesParams[i].ucBitDepthChromaMinus8 = 2;
935             surfacesParams[i].ucBitDepthLumaMinus8   = 2;
936             break;
937         }
938         default: {
939             surfacesParams[i].ucBitDepthChromaMinus8 = 0;
940             surfacesParams[i].ucBitDepthLumaMinus8   = 0;
941             break;
942         }
943         }
944     }
945 
946     ENCODE_CHK_STATUS_RETURN(m_basicFeature->m_ref.SetHcpSurfaceParams(surfacesParams));
947 
948     // Program surface params for reconstructed surface
949     surfacesParams[CODECHAL_HCP_DECODED_SURFACE_ID].psSurface         = &m_basicFeature->m_reconSurface;
950     surfacesParams[CODECHAL_HCP_DECODED_SURFACE_ID].dwReconSurfHeight = m_basicFeature->m_rawSurfaceToPak->dwHeight;
951 
952     // Program surface params for source surface
953     surfacesParams[CODECHAL_HCP_SRC_SURFACE_ID].psSurface             = m_basicFeature->m_rawSurfaceToPak;
954     surfacesParams[CODECHAL_HCP_SRC_SURFACE_ID].bDisplayFormatSwizzle = m_vp9SeqParams->SeqFlags.fields.DisplayFormatSwizzle;
955     surfacesParams[CODECHAL_HCP_SRC_SURFACE_ID].dwActualWidth         = MOS_ALIGN_CEIL(m_basicFeature->m_oriFrameWidth, CODEC_VP9_MIN_BLOCK_WIDTH);
956     surfacesParams[CODECHAL_HCP_SRC_SURFACE_ID].dwActualHeight        = MOS_ALIGN_CEIL(m_basicFeature->m_oriFrameHeight, CODEC_VP9_MIN_BLOCK_HEIGHT);
957 
958     return MOS_STATUS_SUCCESS;
959 }
960 
AddHcpIndObjBaseAddrCmd(MOS_COMMAND_BUFFER & cmdBuffer)961 MOS_STATUS Vp9VdencPkt::AddHcpIndObjBaseAddrCmd(MOS_COMMAND_BUFFER &cmdBuffer)
962 {
963     ENCODE_FUNC_CALL();
964 
965     SETPAR_AND_ADDCMD(HCP_IND_OBJ_BASE_ADDR_STATE, m_hcpInterfaceNew, &cmdBuffer);
966 
967     return MOS_STATUS_SUCCESS;
968 }
969 
AddVdencPipeModeSelectCmd(MOS_COMMAND_BUFFER & cmdBuffer)970 MOS_STATUS Vp9VdencPkt::AddVdencPipeModeSelectCmd(MOS_COMMAND_BUFFER &cmdBuffer)
971 {
972     ENCODE_FUNC_CALL();
973 
974     SETPAR_AND_ADDCMD(VDENC_PIPE_MODE_SELECT, m_vdencInterfaceNew, &cmdBuffer);
975 
976     return MOS_STATUS_SUCCESS;
977 }
978 
SetVdencDsSurfaceParams(MHW_VDBOX_SURFACE_PARAMS * dsSurfaceParams)979 MOS_STATUS Vp9VdencPkt::SetVdencDsSurfaceParams(MHW_VDBOX_SURFACE_PARAMS *dsSurfaceParams)
980 {
981     ENCODE_FUNC_CALL();
982 
983     // 8xDS surface
984     MOS_ZeroMemory(&dsSurfaceParams[0], sizeof(MHW_VDBOX_SURFACE_PARAMS));
985     dsSurfaceParams[0].Mode             = m_basicFeature->m_mode;
986     dsSurfaceParams[0].ucSurfaceStateId = CODECHAL_MFX_DSRECON_SURFACE_ID;
987     dsSurfaceParams[0].psSurface        = m_basicFeature->m_8xDSSurface;
988     // 4xDS Surface
989     MOS_ZeroMemory(&dsSurfaceParams[1], sizeof(MHW_VDBOX_SURFACE_PARAMS));
990     dsSurfaceParams[1].Mode             = m_basicFeature->m_mode;
991     dsSurfaceParams[1].ucSurfaceStateId = CODECHAL_MFX_DSRECON_SURFACE_ID;
992     dsSurfaceParams[1].psSurface        = m_basicFeature->m_4xDSSurface;
993 
994     return MOS_STATUS_SUCCESS;
995 }
996 
AddVdencSurfacesStateCmd(MOS_COMMAND_BUFFER & cmdBuffer)997 MOS_STATUS Vp9VdencPkt::AddVdencSurfacesStateCmd(MOS_COMMAND_BUFFER &cmdBuffer)
998 {
999     ENCODE_FUNC_CALL();
1000 
1001     ENCODE_CHK_STATUS_RETURN(m_basicFeature->m_ref.SetVdencSurfaceParams(m_surfacesParams));
1002 
1003     // Set VDENC source surface parameters
1004     SETPAR_AND_ADDCMD(VDENC_SRC_SURFACE_STATE, m_vdencInterfaceNew, &cmdBuffer);
1005 
1006     // Set VDENC recon surface parameters.
1007     // Check picture coding type:
1008     // - if I_TYPE, recon surface for reference
1009     // - otherwise, use LAST_SURFACE, or GOLDEN_SURFACE or ALTREF_SURFACE for reference
1010     if (m_basicFeature->m_pictureCodingType == I_TYPE)
1011     {
1012         m_curVdencSurfStateId = CODECHAL_HCP_DECODED_SURFACE_ID;
1013         SETPAR_AND_ADDCMD(VDENC_REF_SURFACE_STATE, m_vdencInterfaceNew, &cmdBuffer);
1014     }
1015     else
1016     {
1017         m_curVdencSurfStateId = CODECHAL_HCP_LAST_SURFACE_ID;
1018         SETPAR_AND_ADDCMD(VDENC_REF_SURFACE_STATE, m_vdencInterfaceNew, &cmdBuffer);
1019 
1020         auto dysRefFrameFlags = m_basicFeature->m_ref.DysRefFrameFlags();
1021         auto dysVdencMultiPassEnabled = m_basicFeature->m_dysVdencMultiPassEnabled;
1022 
1023         if ((dysRefFrameFlags != DYS_REF_NONE) && !dysVdencMultiPassEnabled)
1024         {
1025             auto refFrameFlags = m_basicFeature->m_ref.RefFrameFlags();
1026             if (refFrameFlags & 0x02)
1027             {
1028                 m_curVdencSurfStateId = CODECHAL_HCP_GOLDEN_SURFACE_ID;
1029                 SETPAR_AND_ADDCMD(VDENC_REF_SURFACE_STATE, m_vdencInterfaceNew, &cmdBuffer);
1030             }
1031             if (refFrameFlags & 0x04)
1032             {
1033                 m_curVdencSurfStateId = CODECHAL_HCP_ALTREF_SURFACE_ID;
1034                 SETPAR_AND_ADDCMD(VDENC_REF_SURFACE_STATE, m_vdencInterfaceNew, &cmdBuffer);
1035             }
1036         }
1037     }
1038 
1039     // Set 4x, 8x scaled surfaces
1040     SETPAR_AND_ADDCMD(VDENC_DS_REF_SURFACE_STATE, m_vdencInterfaceNew, &cmdBuffer);
1041 
1042     return MOS_STATUS_SUCCESS;
1043 }
1044 
SetVdencPipeModeSelectParams(MHW_VDBOX_PIPE_MODE_SELECT_PARAMS & vdboxPipeModeSelectParams)1045 MOS_STATUS Vp9VdencPkt::SetVdencPipeModeSelectParams(MHW_VDBOX_PIPE_MODE_SELECT_PARAMS &vdboxPipeModeSelectParams)
1046 {
1047     ENCODE_FUNC_CALL();
1048 
1049     auto brcFeature = dynamic_cast<Vp9EncodeBrc *>(m_featureManager->GetFeature(Vp9FeatureIDs::vp9BrcFeature));
1050     ENCODE_CHK_NULL_RETURN(brcFeature);
1051 
1052     vdboxPipeModeSelectParams                                = {};
1053     vdboxPipeModeSelectParams.Mode                           = m_basicFeature->m_mode;
1054     vdboxPipeModeSelectParams.bStreamOutEnabled              = brcFeature->IsVdencBrcEnabled();
1055     vdboxPipeModeSelectParams.bVdencEnabled                  = true;
1056     vdboxPipeModeSelectParams.bVdencPakObjCmdStreamOutEnable = m_vdencPakObjCmdStreamOutEnabled;
1057     vdboxPipeModeSelectParams.bTlbPrefetchEnable             = true;
1058 
1059     // Add 1 to compensate for VdencPipeModeSelect params values
1060     vdboxPipeModeSelectParams.ChromaType = m_basicFeature->m_vp9SeqParams->SeqFlags.fields.EncodedFormat + 1;
1061     switch (m_basicFeature->m_vp9SeqParams->SeqFlags.fields.EncodedBitDepth)
1062     {
1063     case VP9_ENCODED_BIT_DEPTH_10: {
1064         vdboxPipeModeSelectParams.ucVdencBitDepthMinus8 = 2;
1065         break;
1066     }
1067     default: {
1068         vdboxPipeModeSelectParams.ucVdencBitDepthMinus8 = 0;
1069         break;
1070     }
1071     }
1072 
1073     return MOS_STATUS_SUCCESS;
1074 }
1075 
AddVdencPipeBufAddrCmd(MOS_COMMAND_BUFFER & cmdBuffer)1076 MOS_STATUS Vp9VdencPkt::AddVdencPipeBufAddrCmd(MOS_COMMAND_BUFFER &cmdBuffer)
1077 {
1078     if (m_basicFeature->m_ref.DysRefFrameFlags() == DYS_REF_NONE)
1079     {
1080         m_resVdencPakObjCmdStreamOutBuffer = m_basicFeature->m_resMbCodeBuffer;
1081     }
1082 
1083     SETPAR_AND_ADDCMD(VDENC_PIPE_BUF_ADDR_STATE, m_vdencInterfaceNew, &cmdBuffer);
1084 
1085     return MOS_STATUS_SUCCESS;
1086 }
1087 
SetVdencPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & pipeBufAddrParams)1088 MOS_STATUS Vp9VdencPkt::SetVdencPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS &pipeBufAddrParams)
1089 {
1090     ENCODE_FUNC_CALL();
1091 
1092     pipeBufAddrParams.presVdencTileRowStoreBuffer                = &m_vdencTileRowStoreBuffer;
1093     pipeBufAddrParams.presVdencCumulativeCuCountStreamoutSurface = &m_vdencCumulativeCuCountStreamoutSurface;
1094 
1095     auto dysRefFrameFlags         = m_basicFeature->m_ref.DysRefFrameFlags();
1096     auto dysVdencMultiPassEnabled = m_basicFeature->m_dysVdencMultiPassEnabled;
1097 
1098     pipeBufAddrParams.bDynamicScalingEnable = (dysRefFrameFlags != DYS_REF_NONE) && !dysVdencMultiPassEnabled;
1099     pipeBufAddrParams.pRawSurfParam         = &m_surfacesParams[CODECHAL_HCP_SRC_SURFACE_ID];
1100     pipeBufAddrParams.pDecodedReconParam    = &m_surfacesParams[CODECHAL_HCP_DECODED_SURFACE_ID];
1101 
1102     return MOS_STATUS_SUCCESS;
1103 }
1104 
SetPipeBufAddrMmcState(PMHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams)1105 MOS_STATUS Vp9VdencPkt::SetPipeBufAddrMmcState(PMHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams)
1106 {
1107     ENCODE_FUNC_CALL();
1108     ENCODE_CHK_NULL_RETURN(m_mmcState);
1109 
1110     if (m_mmcState->IsMmcEnabled())
1111     {
1112         ENCODE_CHK_STATUS_RETURN(m_mmcState->GetSurfaceMmcState(&m_basicFeature->m_reconSurface, &pipeBufAddrParams->PreDeblockSurfMmcState));
1113         pipeBufAddrParams->PostDeblockSurfMmcState = pipeBufAddrParams->PreDeblockSurfMmcState;
1114         ENCODE_CHK_STATUS_RETURN(m_mmcState->GetSurfaceMmcState(&m_basicFeature->m_rawSurface, &pipeBufAddrParams->RawSurfMmcState));
1115     }
1116     else
1117     {
1118         pipeBufAddrParams->PreDeblockSurfMmcState  = MOS_MEMCOMP_DISABLED;
1119         pipeBufAddrParams->PostDeblockSurfMmcState = MOS_MEMCOMP_DISABLED;
1120         pipeBufAddrParams->RawSurfMmcState         = MOS_MEMCOMP_DISABLED;
1121     }
1122 
1123     CODECHAL_DEBUG_TOOL(
1124         m_basicFeature->m_reconSurface.MmcState = pipeBufAddrParams->PreDeblockSurfMmcState;)
1125 
1126     return MOS_STATUS_SUCCESS;
1127 }
1128 
AddVdencSecondLevelBatchBufferCmd(MOS_COMMAND_BUFFER & cmdBuffer)1129 MOS_STATUS Vp9VdencPkt::AddVdencSecondLevelBatchBufferCmd(MOS_COMMAND_BUFFER &cmdBuffer)
1130 {
1131     ENCODE_FUNC_CALL();
1132 
1133     MHW_BATCH_BUFFER secondLevelBatchBuffer;
1134     MOS_ZeroMemory(&secondLevelBatchBuffer, sizeof(secondLevelBatchBuffer));
1135     RUN_FEATURE_INTERFACE_RETURN(Vp9EncodePak, Vp9FeatureIDs::vp9PakFeature, SetVdencSecondLevelBatchBuffer, m_pipeline->GetCurrentPass(), secondLevelBatchBuffer);
1136     ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_BATCH_BUFFER_START)(&cmdBuffer, &secondLevelBatchBuffer));
1137 
1138     return MOS_STATUS_SUCCESS;
1139 }
1140 
SetSurfaceMmcState(PMHW_VDBOX_SURFACE_PARAMS surfaceStateParams)1141 MOS_STATUS Vp9VdencPkt::SetSurfaceMmcState(PMHW_VDBOX_SURFACE_PARAMS surfaceStateParams)
1142 {
1143     ENCODE_CHK_NULL_RETURN(surfaceStateParams);
1144     ENCODE_CHK_NULL_RETURN(surfaceStateParams->psSurface);
1145     ENCODE_CHK_NULL_RETURN(m_mmcState);
1146 
1147     ENCODE_FUNC_CALL();
1148 
1149     if (m_mmcState->IsMmcEnabled())
1150     {
1151         ENCODE_CHK_STATUS_RETURN(m_mmcState->GetSurfaceMmcState(surfaceStateParams->psSurface, &surfaceStateParams->mmcState));
1152         ENCODE_CHK_STATUS_RETURN(m_mmcState->GetSurfaceMmcFormat(surfaceStateParams->psSurface, &surfaceStateParams->dwCompressionFormat));
1153     }
1154     else
1155     {
1156         surfaceStateParams->mmcState = MOS_MEMCOMP_DISABLED;
1157     }
1158 
1159     return MOS_STATUS_SUCCESS;
1160 }
1161 
StartStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)1162 MOS_STATUS Vp9VdencPkt::StartStatusReport(uint32_t srType, MOS_COMMAND_BUFFER *cmdBuffer)
1163 {
1164     ENCODE_FUNC_CALL();
1165     ENCODE_CHK_NULL_RETURN(cmdBuffer);
1166 
1167     ENCODE_CHK_STATUS_RETURN(MediaPacket::StartStatusReportNext(srType, cmdBuffer));
1168     m_encodecp->StartCpStatusReport(cmdBuffer);
1169 
1170     MediaPerfProfiler *perfProfiler = MediaPerfProfiler::Instance();
1171     ENCODE_CHK_NULL_RETURN(perfProfiler);
1172     ENCODE_CHK_STATUS_RETURN(perfProfiler->AddPerfCollectStartCmd(
1173         (void *)m_pipeline, m_osInterface, m_miItf, cmdBuffer));
1174 
1175     return MOS_STATUS_SUCCESS;
1176 }
1177 
EndStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)1178 MOS_STATUS Vp9VdencPkt::EndStatusReport(uint32_t srType, MOS_COMMAND_BUFFER *cmdBuffer)
1179 {
1180     ENCODE_FUNC_CALL();
1181     ENCODE_CHK_NULL_RETURN(cmdBuffer);
1182 
1183     ENCODE_CHK_STATUS_RETURN(MediaPacket::EndStatusReportNext(srType, cmdBuffer));
1184 
1185     MediaPerfProfiler *perfProfiler = MediaPerfProfiler::Instance();
1186     ENCODE_CHK_NULL_RETURN(perfProfiler);
1187     ENCODE_CHK_STATUS_RETURN(perfProfiler->AddPerfCollectEndCmd(
1188         (void *)m_pipeline, m_osInterface, m_miItf, cmdBuffer));
1189 
1190     return MOS_STATUS_SUCCESS;
1191 }
1192 
EnsureAllCommandsExecuted(MOS_COMMAND_BUFFER & cmdBuffer)1193 MOS_STATUS Vp9VdencPkt::EnsureAllCommandsExecuted(MOS_COMMAND_BUFFER &cmdBuffer)
1194 {
1195     ENCODE_FUNC_CALL();
1196 
1197     // Flush the engine to ensure memory written out
1198     auto &flushDwParams                         = m_miItf->MHW_GETPAR_F(MI_FLUSH_DW)();
1199     flushDwParams                               = {};
1200     flushDwParams.bVideoPipelineCacheInvalidate = true;
1201     ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(&cmdBuffer));
1202 
1203     return MOS_STATUS_SUCCESS;
1204 }
1205 
ReadHcpStatus(MHW_VDBOX_NODE_IND vdboxIndex,MediaStatusReport * statusReport,MOS_COMMAND_BUFFER & cmdBuffer)1206 MOS_STATUS Vp9VdencPkt::ReadHcpStatus(
1207     MHW_VDBOX_NODE_IND  vdboxIndex,
1208     MediaStatusReport * statusReport,
1209     MOS_COMMAND_BUFFER &cmdBuffer)
1210 {
1211     ENCODE_FUNC_CALL();
1212 
1213     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1214 
1215     CODEC_HW_FUNCTION_ENTER;
1216 
1217     ENCODE_CHK_NULL_RETURN(statusReport);
1218     ENCODE_CHK_NULL_RETURN(m_hwInterface);
1219 
1220     ENCODE_CHK_COND_RETURN((vdboxIndex > m_hwInterface->GetMaxVdboxIndex()), "ERROR - vdbox index exceed the maximum");
1221 
1222     MOS_RESOURCE *osResource = nullptr;
1223     uint32_t      offset     = 0;
1224 
1225     EncodeStatusReadParams params;
1226     MOS_ZeroMemory(&params, sizeof(params));
1227 
1228     ENCODE_CHK_STATUS_RETURN(statusReport->GetAddress(encode::statusReportMfxBitstreamByteCountPerFrame, osResource, offset));
1229     params.resBitstreamByteCountPerFrame    = osResource;
1230     params.bitstreamByteCountPerFrameOffset = offset;
1231 
1232     auto &flushDwParams = m_miItf->MHW_GETPAR_F(MI_FLUSH_DW)();
1233     flushDwParams       = {};
1234     ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(&cmdBuffer));
1235 
1236     auto mmioRegisters = m_hcpInterfaceNew->GetMmioRegisters(vdboxIndex);
1237     auto &miStoreRegMemParams           = m_miItf->MHW_GETPAR_F(MI_STORE_REGISTER_MEM)();
1238     miStoreRegMemParams                 = {};
1239     miStoreRegMemParams.presStoreBuffer = params.resBitstreamByteCountPerFrame;
1240     miStoreRegMemParams.dwOffset        = params.bitstreamByteCountPerFrameOffset;
1241     miStoreRegMemParams.dwRegister      = mmioRegisters->hcpVp9EncBitstreamBytecountFrameRegOffset;
1242     ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_REGISTER_MEM)(&cmdBuffer));
1243 
1244     auto brcFeature = dynamic_cast<Vp9EncodeBrc *>(m_featureManager->GetFeature(Vp9FeatureIDs::vp9BrcFeature));
1245     ENCODE_CHK_NULL_RETURN(brcFeature);
1246 
1247     HucBrcBuffers *hucBrcBuffers = nullptr;
1248     ENCODE_CHK_STATUS_RETURN(brcFeature->GetHucBrcBuffers(hucBrcBuffers));
1249     ENCODE_CHK_NULL_RETURN(hucBrcBuffers);
1250 
1251     auto &copyMemMemParams       = m_miItf->MHW_GETPAR_F(MI_COPY_MEM_MEM)();
1252     copyMemMemParams             = {};
1253     copyMemMemParams.presSrc     = params.resBitstreamByteCountPerFrame;
1254     copyMemMemParams.dwSrcOffset = params.bitstreamByteCountPerFrameOffset;
1255     copyMemMemParams.presDst     = &hucBrcBuffers->resBrcBitstreamSizeBuffer;
1256     copyMemMemParams.dwDstOffset = CODECHAL_OFFSETOF(EncodeVp9BSBuffer, dwHcpBitstreamByteCountFrame);
1257     ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_COPY_MEM_MEM)(&cmdBuffer));
1258 
1259     // Write frame size directly to huc second pass dmem buffer.
1260     // It is needed for correct pipeline synchronization and dmem initialization
1261     PMOS_RESOURCE hucProbDmemBuffer = nullptr;
1262     // For BRC cases, do not overwrite the HPU probability in huc Dmen buffer in the last pass
1263     uint32_t idx = brcFeature->IsVdencBrcEnabled() ? 2 : 1;
1264     RUN_FEATURE_INTERFACE_RETURN(Vp9EncodeHpu, Vp9FeatureIDs::vp9HpuFeature, GetHucProbDmemBuffer, idx, hucProbDmemBuffer);
1265     ENCODE_CHK_NULL_RETURN(hucProbDmemBuffer);
1266 
1267     copyMemMemParams             = {};
1268     copyMemMemParams.presSrc     = params.resBitstreamByteCountPerFrame;
1269     copyMemMemParams.dwSrcOffset = params.bitstreamByteCountPerFrameOffset;
1270     copyMemMemParams.presDst     = hucProbDmemBuffer;
1271     copyMemMemParams.dwDstOffset = CODECHAL_OFFSETOF(HucProbDmem, FrameSize);
1272     ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_COPY_MEM_MEM)(&cmdBuffer));
1273 
1274     return eStatus;
1275 }
1276 
UpdateParameters()1277 MOS_STATUS Vp9VdencPkt::UpdateParameters()
1278 {
1279     ENCODE_FUNC_CALL();
1280 
1281     auto isLastPipe = m_pipeline->IsLastPipe();
1282     auto isLastPass = m_pipeline->IsLastPass();
1283 
1284     if (isLastPipe && isLastPass)
1285     {
1286         m_basicFeature->m_contextFrameTypes[m_vp9PicParams->PicFlags.fields.frame_context_idx] = m_vp9PicParams->PicFlags.fields.frame_type;
1287         m_basicFeature->m_prevFrameSegEnabled = m_vp9PicParams->PicFlags.fields.segmentation_enabled;
1288 
1289         // If Huc super frame enabled, update m_prevFrameInfo in super frame pass packet
1290         if (!(m_basicFeature->m_vp9PicParams->PicFlags.fields.super_frame && m_basicFeature->m_tsEnabled))
1291         {
1292             ENCODE_CHK_STATUS_RETURN(m_basicFeature->UpdateParameters());
1293         }
1294     }
1295 
1296     if (isLastPipe)
1297     {
1298         RUN_FEATURE_INTERFACE_RETURN(Vp9EncodePak, Vp9FeatureIDs::vp9PakFeature, UpdateParameters);
1299     }
1300 
1301     return MOS_STATUS_SUCCESS;
1302 }
1303 
DumpInput()1304 MOS_STATUS Vp9VdencPkt::DumpInput()
1305 {
1306     ENCODE_FUNC_CALL();
1307 
1308 #if USE_CODECHAL_DEBUG_TOOL
1309     // Dump output (resource, information, etc) before command submitted
1310     CodechalDebugInterface *debugInterface = m_pipeline->GetDebugInterface();
1311     ENCODE_CHK_NULL_RETURN(debugInterface);
1312 
1313     CODEC_REF_LIST currRefList = *((CODEC_REF_LIST *)m_basicFeature->m_ref.GetCurrRefList());
1314 
1315     std::stringstream pipeIdxStrStream;
1316     pipeIdxStrStream << "_" << (int)m_pipeline->GetCurrentPipe();
1317 
1318     std::string bufferPassName = GetPacketName();
1319     bufferPassName += pipeIdxStrStream.str() + "_input";
1320 
1321     std::string surfacePassName = "PASS" + std::to_string((uint32_t)m_pipeline->GetCurrentPass());
1322     surfacePassName += pipeIdxStrStream.str() + "_input";
1323 
1324     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
1325         &currRefList.resBitstreamBuffer,
1326         CodechalDbgAttr::attrBitstream,
1327         bufferPassName.data(),
1328         m_basicFeature->m_bitstreamSize,
1329         0,
1330         CODECHAL_NUM_MEDIA_STATES));
1331 
1332     if (m_basicFeature->m_ref.DysRefFrameFlags() == DYS_REF_NONE && m_resVdencPakObjCmdStreamOutBuffer != nullptr)
1333     {
1334         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
1335             m_resVdencPakObjCmdStreamOutBuffer,
1336             CodechalDbgAttr::attrPakObjStreamout,
1337             bufferPassName.data(),
1338             m_basicFeature->m_mbCodeSize + 8 * CODECHAL_CACHELINE_SIZE,
1339             0,
1340             CODECHAL_NUM_MEDIA_STATES));
1341     }
1342 
1343     MOS_RESOURCE *mbCodedBuffer = m_basicFeature->m_trackedBuf->GetBuffer(
1344         BufferType::mbCodedBuffer, currRefList.ucScalingIdx);
1345     if (mbCodedBuffer != nullptr)
1346     {
1347         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
1348             mbCodedBuffer,
1349             CodechalDbgAttr::attrVdencOutput,
1350             (bufferPassName + "_MbCode").data(),
1351             m_basicFeature->m_mbCodeSize + 8 * CODECHAL_CACHELINE_SIZE,
1352             0,
1353             CODECHAL_NUM_MEDIA_STATES));
1354     }
1355 
1356     PMOS_RESOURCE frameStatStreamOutBuffer = m_basicFeature->m_recycleBuf->GetBuffer(FrameStatStreamOutBuffer, 0);
1357     ENCODE_CHK_NULL_RETURN(frameStatStreamOutBuffer);
1358     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
1359         frameStatStreamOutBuffer,
1360         CodechalDbgAttr::attrFrameState,
1361         bufferPassName.data(),
1362         frameStatStreamOutBuffer->iSize,
1363         0,
1364         CODECHAL_NUM_MEDIA_STATES));
1365 
1366     auto          streamInBufferSize = (MOS_ALIGN_CEIL(m_basicFeature->m_frameWidth, 64) / 32) * (MOS_ALIGN_CEIL(m_basicFeature->m_frameHeight, 64) / 32) * CODECHAL_CACHELINE_SIZE;
1367     PMOS_RESOURCE streamInBuffer     = m_basicFeature->m_recycleBuf->GetBuffer(RecycleResId::StreamInBuffer, m_basicFeature->m_frameNum);
1368     if (streamInBuffer != nullptr)
1369     {
1370         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
1371             streamInBuffer,
1372             CodechalDbgAttr::attrStreamIn,
1373             bufferPassName.data(),
1374             streamInBufferSize,
1375             0,
1376             CODECHAL_NUM_MEDIA_STATES));
1377     }
1378 
1379     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBltOutput(
1380         &currRefList.sRefReconBuffer,
1381         CodechalDbgAttr::attrDecodeBltOutput));
1382     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
1383         &currRefList.sRefReconBuffer,
1384         CodechalDbgAttr::attrReconstructedSurface,
1385         (surfacePassName + "_ReconSurf").data()));
1386 
1387     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBltOutput(
1388         &currRefList.sRefRawBuffer,
1389         CodechalDbgAttr::attrDecodeBltOutput));
1390     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
1391         &currRefList.sRefRawBuffer,
1392         CodechalDbgAttr::attrEncodeRawInputSurface,
1393         (surfacePassName + "_SrcSurf").data()));
1394 
1395     ENCODE_CHK_STATUS_RETURN(m_basicFeature->m_ref.DumpInput(m_pipeline));
1396 #endif
1397 
1398     return MOS_STATUS_SUCCESS;
1399 }
1400 
1401 #if USE_CODECHAL_DEBUG_TOOL
1402 
DumpResources(EncodeStatusMfx * encodeStatusMfx,EncodeStatusReportData * statusReportData)1403 MOS_STATUS Vp9VdencPkt::DumpResources(
1404     EncodeStatusMfx *       encodeStatusMfx,
1405     EncodeStatusReportData *statusReportData)
1406 {
1407     ENCODE_FUNC_CALL();
1408     ENCODE_CHK_NULL_RETURN(encodeStatusMfx);
1409     ENCODE_CHK_NULL_RETURN(statusReportData);
1410     ENCODE_CHK_NULL_RETURN(m_pipeline);
1411     ENCODE_CHK_NULL_RETURN(m_statusReport);
1412     ENCODE_CHK_NULL_RETURN(m_basicFeature);
1413     ENCODE_CHK_NULL_RETURN(m_basicFeature->m_trackedBuf);
1414 
1415     CodechalDebugInterface *debugInterface = m_pipeline->GetStatusReportDebugInterface();
1416     ENCODE_CHK_NULL_RETURN(debugInterface);
1417 
1418     CODEC_REF_LIST currRefList = *((CODEC_REF_LIST *)statusReportData->currRefList);
1419     currRefList.RefPic         = statusReportData->currOriginalPic;
1420 
1421     debugInterface->m_currPic            = statusReportData->currOriginalPic;
1422     debugInterface->m_bufferDumpFrameNum = m_statusReport->GetReportedCount() + 1;  // +1 for debug purpose with legacy
1423     debugInterface->m_frameType          = encodeStatusMfx->pictureCodingType;
1424 
1425     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
1426         &currRefList.resBitstreamBuffer,
1427         CodechalDbgAttr::attrBitstream,
1428         "_PAK",
1429         statusReportData->bitstreamSize,
1430         0,
1431         CODECHAL_NUM_MEDIA_STATES));
1432 
1433     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpData(
1434         statusReportData,
1435         sizeof(EncodeStatusReportData),
1436         CodechalDbgAttr::attrStatusReport,
1437         "EncodeStatusReport_Buffer"));
1438 
1439     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpEncodeStatusReport(
1440         statusReportData));
1441 
1442     PMOS_RESOURCE frameStatStreamOutBuffer = m_basicFeature->m_recycleBuf->GetBuffer(FrameStatStreamOutBuffer, 0);
1443     ENCODE_CHK_NULL_RETURN(frameStatStreamOutBuffer);
1444     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
1445         frameStatStreamOutBuffer,
1446         CodechalDbgAttr::attrFrameState,
1447         "FrameStatus",
1448         frameStatStreamOutBuffer->iSize,
1449         0,
1450         CODECHAL_NUM_MEDIA_STATES));
1451 
1452     MOS_SURFACE *ds4xSurface = m_basicFeature->m_trackedBuf->GetSurface(
1453         BufferType::ds4xSurface, currRefList.ucScalingIdx);
1454     if (ds4xSurface != nullptr)
1455     {
1456         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
1457             ds4xSurface,
1458             CodechalDbgAttr::attrReconstructedSurface,
1459             "4xScaledSurf"));
1460     }
1461 
1462     MOS_SURFACE *ds8xSurface = m_basicFeature->m_trackedBuf->GetSurface(
1463         BufferType::ds8xSurface, currRefList.ucScalingIdx);
1464     if (ds8xSurface != nullptr)
1465     {
1466         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
1467             ds8xSurface,
1468             CodechalDbgAttr::attrReconstructedSurface,
1469             "8xScaledSurf"));
1470     }
1471 
1472     MOS_RESOURCE *mbCodedBuffer = m_basicFeature->m_trackedBuf->GetBuffer(
1473         BufferType::mbCodedBuffer, currRefList.ucScalingIdx);
1474     if (mbCodedBuffer != nullptr)
1475     {
1476         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
1477             mbCodedBuffer,
1478             CodechalDbgAttr::attrVdencOutput,
1479             "_MbCode",
1480             m_basicFeature->m_mbCodeSize + 8 * CODECHAL_CACHELINE_SIZE,
1481             0,
1482             CODECHAL_NUM_MEDIA_STATES));
1483     }
1484 
1485     auto          streamInBufferSize = (MOS_ALIGN_CEIL(m_basicFeature->m_frameWidth, 64) / 32) * (MOS_ALIGN_CEIL(m_basicFeature->m_frameHeight, 64) / 32) * CODECHAL_CACHELINE_SIZE;
1486     PMOS_RESOURCE streamInBuffer     = m_basicFeature->m_recycleBuf->GetBuffer(RecycleResId::StreamInBuffer, m_basicFeature->m_frameNum);
1487     if (streamInBuffer != nullptr)
1488     {
1489         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer(
1490             streamInBuffer,
1491             CodechalDbgAttr::attrStreamIn,
1492             "StreamIn",
1493             streamInBufferSize,
1494             0,
1495             CODECHAL_NUM_MEDIA_STATES));
1496     }
1497 
1498     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBltOutput(
1499         &currRefList.sRefReconBuffer,
1500         CodechalDbgAttr::attrDecodeBltOutput));
1501     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
1502         &currRefList.sRefReconBuffer,
1503         CodechalDbgAttr::attrReconstructedSurface,
1504         "ReconSurf"));
1505 
1506     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBltOutput(
1507         &currRefList.sRefRawBuffer,
1508         CodechalDbgAttr::attrDecodeBltOutput));
1509     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface(
1510         &currRefList.sRefRawBuffer,
1511         CodechalDbgAttr::attrEncodeRawInputSurface,
1512         "SrcSurf"));
1513 
1514     return MOS_STATUS_SUCCESS;
1515 }
1516 
1517 #endif
1518 
MmcEnabled(MOS_MEMCOMP_STATE state)1519 static bool MmcEnabled(MOS_MEMCOMP_STATE state)
1520 {
1521     return state == MOS_MEMCOMP_RC || state == MOS_MEMCOMP_MC;
1522 }
1523 
MmcRcEnabled(MOS_MEMCOMP_STATE state)1524 static bool MmcRcEnabled(MOS_MEMCOMP_STATE state)
1525 {
1526     return state == MOS_MEMCOMP_RC;
1527 }
1528 
MHW_SETPAR_DECL_SRC(HCP_SURFACE_STATE,Vp9VdencPkt)1529 MHW_SETPAR_DECL_SRC(HCP_SURFACE_STATE, Vp9VdencPkt)
1530 {
1531     ENCODE_FUNC_CALL();
1532 
1533     params.surfaceStateId = m_curHcpSurfStateId;
1534 
1535     auto surfParams = m_surfacesParams[m_curHcpSurfStateId];
1536 
1537     PMOS_SURFACE psSurface            = surfParams.psSurface;
1538     uint32_t     reconSurfHeight      = surfParams.dwReconSurfHeight;
1539     uint8_t      chromaType           = surfParams.ChromaType;
1540     uint8_t      ucBitDepthLumaMinus8 = surfParams.ucBitDepthLumaMinus8;
1541 
1542     ENCODE_CHK_NULL_RETURN(psSurface);
1543 
1544     params.surfacePitchMinus1 = psSurface->dwPitch - 1;
1545 
1546     /* Handling of reconstructed surface is different for Y410 & AYUV formats */
1547     if ((params.surfaceStateId != CODECHAL_HCP_SRC_SURFACE_ID) &&
1548         (psSurface->Format == Format_Y410))
1549         params.surfacePitchMinus1 = psSurface->dwPitch / 2 - 1;
1550 
1551     if ((params.surfaceStateId != CODECHAL_HCP_SRC_SURFACE_ID) &&
1552         (psSurface->Format == Format_AYUV))
1553         params.surfacePitchMinus1 = psSurface->dwPitch / 4 - 1;
1554 
1555     bool surf10bit = (psSurface->Format == Format_P010) ||
1556                      (psSurface->Format == Format_P210) ||
1557                      (psSurface->Format == Format_Y210) ||
1558                      (psSurface->Format == Format_Y410) ||
1559                      (psSurface->Format == Format_R10G10B10A2) ||
1560                      (psSurface->Format == Format_B10G10R10A2) ||
1561                      (psSurface->Format == Format_P016) ||
1562                      (psSurface->Format == Format_Y216);
1563 
1564     if (chromaType == HCP_CHROMA_FORMAT_YUV422)
1565     {
1566         if (ucBitDepthLumaMinus8 > 0)
1567         {
1568             if (params.surfaceStateId == CODECHAL_HCP_SRC_SURFACE_ID)
1569             {
1570                 params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_Y216VARIANT;
1571 
1572                 if (surf10bit)
1573                 {
1574                     params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_Y216Y210FORMAT;
1575                 }
1576             }
1577         }
1578         else
1579         {
1580             params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_YUY2VARIANT;
1581 
1582             if (params.surfaceStateId == CODECHAL_HCP_SRC_SURFACE_ID)
1583             {
1584                 params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_YUY2FORMAT;
1585             }
1586         }
1587     }
1588     else if (chromaType == HCP_CHROMA_FORMAT_YUV444)
1589     {
1590         if (ucBitDepthLumaMinus8 == 0)
1591         {
1592             params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_AYUV4444VARIANT;
1593 
1594             if (params.surfaceStateId == CODECHAL_HCP_SRC_SURFACE_ID)
1595             {
1596                 params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_AYUV4444FORMAT;
1597             }
1598         }
1599         else if (ucBitDepthLumaMinus8 <= 2)
1600         {
1601             if (params.surfaceStateId == CODECHAL_HCP_SRC_SURFACE_ID)
1602             {
1603                 params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_AYUV4444FORMAT;
1604 
1605                 if (surf10bit)
1606                 {
1607                     params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_Y410FORMAT;
1608                 }
1609             }
1610             else
1611             {
1612                 params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_Y416VARIANT;
1613             }
1614         }
1615         else
1616         {
1617             params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_Y416FORMAT;
1618         }
1619     }
1620     else  //chromaType == HCP_CHROMA_FORMAT_YUV420
1621     {
1622         if (ucBitDepthLumaMinus8 > 0)
1623         {
1624             if (params.surfaceStateId == CODECHAL_HCP_SRC_SURFACE_ID)
1625             {
1626                 params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_PLANAR4208;
1627 
1628                 if (surf10bit)
1629                 {
1630                     params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_P010;
1631                 }
1632             }
1633             else
1634             {
1635                 params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_P010VARIANT;
1636             }
1637         }
1638         else
1639         {
1640             params.surfaceFormat = hcp::SURFACE_FORMAT::SURFACE_FORMAT_PLANAR4208;
1641         }
1642     }
1643 
1644     params.yOffsetForUCbInPixel = params.yOffsetForVCr =
1645         (uint16_t)((psSurface->UPlaneOffset.iSurfaceOffset - psSurface->dwOffset) / psSurface->dwPitch + psSurface->RenderOffset.YUV.U.YOffset);
1646 
1647     //Set U/V offsets for Variant surfaces
1648     if (params.surfaceFormat == hcp::SURFACE_FORMAT::SURFACE_FORMAT_Y416VARIANT ||
1649         params.surfaceFormat == hcp::SURFACE_FORMAT::SURFACE_FORMAT_AYUV4444VARIANT)
1650     {
1651         params.yOffsetForUCbInPixel = (uint16_t)reconSurfHeight;
1652         params.yOffsetForVCr        = (uint16_t)reconSurfHeight << 1;
1653     }
1654     else if (params.surfaceFormat == hcp::SURFACE_FORMAT::SURFACE_FORMAT_Y216VARIANT ||
1655              params.surfaceFormat == hcp::SURFACE_FORMAT::SURFACE_FORMAT_YUY2VARIANT)
1656     {
1657         params.yOffsetForUCbInPixel = params.yOffsetForVCr = (uint16_t)reconSurfHeight;
1658     }
1659 
1660     params.mmcState            = surfParams.mmcState;
1661     params.dwCompressionFormat = surfParams.dwCompressionFormat;
1662     params.mmcSkipMask         = surfParams.mmcSkipMask;
1663     params.refsMmcEnable       = (params.surfaceStateId != CODECHAL_HCP_DECODED_SURFACE_ID && MmcEnabled(surfParams.mmcState) )? 0xff : 0;
1664     params.refsMmcType         = (params.surfaceStateId != CODECHAL_HCP_DECODED_SURFACE_ID && MmcRcEnabled(surfParams.mmcState) ) ? 0xff : 0;
1665 
1666     return MOS_STATUS_SUCCESS;
1667 }
1668 
Add_HCP_SURFACE_STATE(PMOS_COMMAND_BUFFER & cmdBuffer)1669 MOS_STATUS Vp9VdencPkt::Add_HCP_SURFACE_STATE(PMOS_COMMAND_BUFFER &cmdBuffer)
1670 {
1671     ENCODE_FUNC_CALL();
1672     ENCODE_CHK_NULL_RETURN(cmdBuffer);
1673 
1674     SETPAR_AND_ADDCMD(HCP_SURFACE_STATE, m_hcpInterfaceNew, cmdBuffer);
1675 
1676     return MOS_STATUS_SUCCESS;
1677 }
1678 
AddAllCmds_HCP_SURFACE_STATE(PMOS_COMMAND_BUFFER cmdBuffer)1679 MOS_STATUS Vp9VdencPkt::AddAllCmds_HCP_SURFACE_STATE(PMOS_COMMAND_BUFFER cmdBuffer)
1680 {
1681     ENCODE_FUNC_CALL();
1682     ENCODE_CHK_NULL_RETURN(cmdBuffer);
1683 
1684     // Set HCP_SURFACE_STATE values
1685     SetHcpSurfacesParams(m_surfacesParams);
1686     SetHcpSurfaceMMCState();
1687 
1688     m_curHcpSurfStateId = CODECHAL_HCP_DECODED_SURFACE_ID;
1689     Add_HCP_SURFACE_STATE(cmdBuffer);
1690 
1691     m_curHcpSurfStateId = CODECHAL_HCP_SRC_SURFACE_ID;
1692     Add_HCP_SURFACE_STATE(cmdBuffer);
1693 
1694     auto waTable = m_osInterface == nullptr ? nullptr : m_osInterface->pfnGetWaTable(m_osInterface);
1695     if (waTable)
1696     {
1697         if (MEDIA_IS_WA(waTable, Wa_Vp9UnalignedHeight))
1698         {
1699             uint32_t real_height    = m_basicFeature->m_oriFrameHeight;
1700             uint32_t aligned_height = MOS_ALIGN_CEIL(real_height, CODEC_VP9_MIN_BLOCK_HEIGHT);
1701 
1702             fill_pad_with_value(m_basicFeature->m_rawSurfaceToPak, real_height, aligned_height);
1703         }
1704     }
1705 
1706     // Last reference picture
1707     if (m_surfacesParams[CODECHAL_HCP_LAST_SURFACE_ID].psSurface)
1708     {
1709         m_curHcpSurfStateId = CODECHAL_HCP_LAST_SURFACE_ID;
1710         Add_HCP_SURFACE_STATE(cmdBuffer);
1711     }
1712 
1713     // Golden reference picture
1714     if (m_surfacesParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].psSurface)
1715     {
1716         m_curHcpSurfStateId = CODECHAL_HCP_GOLDEN_SURFACE_ID;
1717         Add_HCP_SURFACE_STATE(cmdBuffer);
1718     }
1719 
1720     // Alt reference picture
1721     if (m_surfacesParams[CODECHAL_HCP_ALTREF_SURFACE_ID].psSurface)
1722     {
1723         m_curHcpSurfStateId = CODECHAL_HCP_ALTREF_SURFACE_ID;
1724         Add_HCP_SURFACE_STATE(cmdBuffer);
1725     }
1726 
1727     return MOS_STATUS_SUCCESS;
1728 }
1729 
getMultiEngineMode() const1730 MHW_VDBOX_HCP_MULTI_ENGINE_MODE Vp9VdencPkt::getMultiEngineMode() const
1731 {
1732     MHW_VDBOX_HCP_MULTI_ENGINE_MODE mode = MHW_VDBOX_HCP_MULTI_ENGINE_MODE_FE_LEGACY;
1733 
1734     if (m_basicFeature->m_scalableMode)
1735     {
1736         // Running in the multiple VDBOX mode
1737         if (m_pipeline->IsFirstPipe())
1738         {
1739             mode = MHW_VDBOX_HCP_MULTI_ENGINE_MODE_LEFT;
1740         }
1741         else if (m_pipeline->IsLastPipe())
1742         {
1743             mode = MHW_VDBOX_HCP_MULTI_ENGINE_MODE_RIGHT;
1744         }
1745         else
1746         {
1747             mode = MHW_VDBOX_HCP_MULTI_ENGINE_MODE_MIDDLE;
1748         }
1749     }
1750 
1751     return mode;
1752 }
1753 
getPipeWorkMode() const1754 MHW_VDBOX_HCP_PIPE_WORK_MODE Vp9VdencPkt::getPipeWorkMode() const
1755 {
1756     if (m_basicFeature->m_scalableMode)
1757     {
1758         return MHW_VDBOX_HCP_PIPE_WORK_MODE_CODEC_BE;
1759     }
1760 
1761     return MHW_VDBOX_HCP_PIPE_WORK_MODE_LEGACY;
1762 }
1763 
MHW_SETPAR_DECL_SRC(HCP_PIPE_MODE_SELECT,Vp9VdencPkt)1764 MHW_SETPAR_DECL_SRC(HCP_PIPE_MODE_SELECT, Vp9VdencPkt)
1765 {
1766     ENCODE_FUNC_CALL();
1767 
1768     params.codecStandardSelect = CODEC_STANDARD_SELECT_VP9;
1769     params.codecSelect         = CODEC_SELECT_ENCODE;
1770 
1771     auto brcFeature = dynamic_cast<Vp9EncodeBrc *>(m_featureManager->GetFeature(Vp9FeatureIDs::vp9BrcFeature));
1772     ENCODE_CHK_NULL_RETURN(brcFeature);
1773 
1774     params.bStreamOutEnabled = brcFeature->IsVdencBrcEnabled();
1775     params.bVdencEnabled     = true;
1776 
1777     return MOS_STATUS_SUCCESS;
1778 }
1779 
MHW_SETPAR_DECL_SRC(HCP_IND_OBJ_BASE_ADDR_STATE,Vp9VdencPkt)1780 MHW_SETPAR_DECL_SRC(HCP_IND_OBJ_BASE_ADDR_STATE, Vp9VdencPkt)
1781 {
1782     ENCODE_FUNC_CALL();
1783 
1784     params.presPakBaseObjectBuffer = &m_basicFeature->m_resBitstreamBuffer;
1785     params.dwPakBaseObjectSize     = m_basicFeature->m_bitstreamUpperBound;
1786 
1787     return MOS_STATUS_SUCCESS;
1788 }
1789 
MHW_SETPAR_DECL_SRC(HCP_PIPE_BUF_ADDR_STATE,Vp9VdencPkt)1790 MHW_SETPAR_DECL_SRC(HCP_PIPE_BUF_ADDR_STATE, Vp9VdencPkt)
1791 {
1792     ENCODE_FUNC_CALL();
1793 
1794     params.psPreDeblockSurface  = &m_basicFeature->m_reconSurface;
1795     params.psPostDeblockSurface = &m_basicFeature->m_reconSurface;
1796     params.psRawSurface         = m_basicFeature->m_rawSurfaceToPak;
1797     params.presCurMvTempBuffer  = m_basicFeature->m_resMvTemporalBuffer;
1798 
1799     params.presVp9SegmentIdBuffer              = m_basicFeature->m_resSegmentIdBuffer;
1800     params.presHvdTileRowStoreBuffer           = const_cast<PMOS_RESOURCE>(&m_resHvcTileRowStoreBuffer);
1801     params.ps4xDsSurface                       = m_basicFeature->m_4xDSSurface;
1802     params.ps8xDsSurface                       = m_basicFeature->m_8xDSSurface;
1803     params.presVdencIntraRowStoreScratchBuffer = const_cast<PMOS_RESOURCE>(&m_resVdencIntraRowStoreScratchBuffer);
1804     params.presSseSrcPixelRowStoreBuffer       = const_cast<PMOS_RESOURCE>(&m_resSseSrcPixelRowStoreBuffer);
1805     params.presVdencStreamInBuffer             = m_basicFeature->m_recycleBuf->GetBuffer(RecycleResId::StreamInBuffer, m_basicFeature->m_frameNum);
1806     params.presSegmentMapStreamOut             = const_cast<PMOS_RESOURCE>(&m_resVdencSegmentMapStreamOut);
1807     params.presPakCuLevelStreamoutBuffer       = const_cast<PMOS_RESOURCE>(&m_resPakcuLevelStreamoutData);
1808     params.presVdencPakObjCmdStreamOutBuffer   = m_resVdencPakObjCmdStreamOutBuffer;
1809 
1810     if ((m_basicFeature->m_ref.DysRefFrameFlags() != DYS_REF_NONE) && !m_vdencPakObjCmdStreamOutEnabled)
1811     {
1812         params.presVdencPakObjCmdStreamOutBuffer = nullptr;
1813     }
1814 
1815     m_basicFeature->m_ref.MHW_SETPAR_F(HCP_PIPE_BUF_ADDR_STATE)(params);
1816 
1817 #ifdef _MMC_SUPPORTED
1818     ENCODE_CHK_NULL_RETURN(m_mmcState);
1819 
1820     if (m_mmcState->IsMmcEnabled())
1821     {
1822         ENCODE_CHK_STATUS_RETURN(m_mmcState->GetSurfaceMmcState(&m_basicFeature->m_reconSurface, &params.PreDeblockSurfMmcState));
1823         params.PostDeblockSurfMmcState = params.PreDeblockSurfMmcState;
1824         ENCODE_CHK_STATUS_RETURN(m_mmcState->GetSurfaceMmcState(&m_basicFeature->m_rawSurface, &params.RawSurfMmcState));
1825     }
1826     else
1827     {
1828         params.PreDeblockSurfMmcState  = MOS_MEMCOMP_DISABLED;
1829         params.PostDeblockSurfMmcState = MOS_MEMCOMP_DISABLED;
1830         params.RawSurfMmcState         = MOS_MEMCOMP_DISABLED;
1831     }
1832 
1833     CODECHAL_DEBUG_TOOL(
1834         m_basicFeature->m_reconSurface.MmcState = params.PreDeblockSurfMmcState;)
1835 #endif
1836 
1837     return MOS_STATUS_SUCCESS;
1838 }
1839 
GetHwTileType(MOS_TILE_TYPE tileType,MOS_TILE_MODE_GMM tileModeGMM,bool gmmTileEnabled)1840 static inline uint32_t GetHwTileType(MOS_TILE_TYPE tileType, MOS_TILE_MODE_GMM tileModeGMM, bool gmmTileEnabled)
1841 {
1842     uint32_t tileMode = 0;
1843 
1844     if (gmmTileEnabled)
1845     {
1846         return tileModeGMM;
1847     }
1848 
1849     switch (tileType)
1850     {
1851     case MOS_TILE_LINEAR:
1852         tileMode = 0;
1853         break;
1854     case MOS_TILE_YS:
1855         tileMode = 1;
1856         break;
1857     case MOS_TILE_X:
1858         tileMode = 2;
1859         break;
1860     default:
1861         tileMode = 3;
1862         break;
1863     }
1864 
1865     return tileMode;
1866 }
1867 
MHW_SETPAR_DECL_SRC(VDENC_REF_SURFACE_STATE,Vp9VdencPkt)1868 MHW_SETPAR_DECL_SRC(VDENC_REF_SURFACE_STATE, Vp9VdencPkt)
1869 {
1870     ENCODE_FUNC_CALL();
1871 
1872     auto surfParams = m_surfacesParams[m_curVdencSurfStateId].psSurface;
1873 
1874     // DW2..5
1875 
1876     params.pitch       = surfParams->dwPitch;
1877     params.tileType    = surfParams->TileType;
1878     params.tileModeGmm = surfParams->TileModeGMM;
1879     params.format      = surfParams->Format;
1880     params.gmmTileEn   = surfParams->bGMMTileEnabled;
1881     params.uOffset     = surfParams->YoffsetForUplane;
1882     params.vOffset     = surfParams->YoffsetForVplane;
1883     params.height      = surfParams->dwHeight;
1884     params.width       = surfParams->dwWidth;
1885     uint32_t tileMode  = GetHwTileType(params.tileType, params.tileModeGmm, params.gmmTileEn);
1886 
1887     if (surfParams->Format == Format_Y410 || surfParams->Format == Format_444P || surfParams->Format == Format_AYUV)
1888     {
1889         if (surfParams->Format == Format_Y410)
1890         {
1891             params.pitch = surfParams->dwPitch / 2;
1892         }
1893         else
1894         {
1895             params.pitch = surfParams->dwPitch / 4;
1896         }
1897         params.uOffset = m_surfacesParams[m_curVdencSurfStateId].dwReconSurfHeight;
1898         params.vOffset = m_surfacesParams[m_curVdencSurfStateId].dwReconSurfHeight << 1;
1899     }
1900     else if (surfParams->Format == Format_Y216 || surfParams->Format == Format_YUY2 || surfParams->Format == Format_YUYV)
1901     {
1902         params.uOffset = m_surfacesParams[m_curVdencSurfStateId].dwReconSurfHeight;
1903         params.vOffset = m_surfacesParams[m_curVdencSurfStateId].dwReconSurfHeight;
1904     }
1905 
1906     return MOS_STATUS_SUCCESS;
1907 }
1908 
MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT,Vp9VdencPkt)1909 MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT, Vp9VdencPkt)
1910 {
1911     ENCODE_FUNC_CALL();
1912 
1913     // DW1
1914 
1915     params.standardSelect                           = CODECHAL_VP9;
1916 
1917     MHW_VDBOX_HCP_MULTI_ENGINE_MODE multiEngineMode = getMultiEngineMode();
1918     params.scalabilityMode                          = !(multiEngineMode == MHW_VDBOX_HCP_MULTI_ENGINE_MODE_FE_LEGACY);
1919 
1920     params.frameStatisticsStreamOut                 = true;
1921     params.pakObjCmdStreamOut                       = m_vdencPakObjCmdStreamOutEnabled;
1922 
1923     return MOS_STATUS_SUCCESS;
1924 }
1925 
MHW_SETPAR_DECL_SRC(VDENC_HEVC_VP9_TILE_SLICE_STATE,Vp9VdencPkt)1926 MHW_SETPAR_DECL_SRC(VDENC_HEVC_VP9_TILE_SLICE_STATE, Vp9VdencPkt)
1927 {
1928     ENCODE_FUNC_CALL();
1929 
1930     uint32_t dwNumberOfPipes = 0;
1931     switch (m_pipeline->GetPipeNum())
1932     {
1933     case 0:
1934     case 1:
1935         dwNumberOfPipes = VDENC_PIPE_SINGLE_PIPE;
1936         break;
1937     case 2:
1938         dwNumberOfPipes = VDENC_PIPE_TWO_PIPE;
1939         break;
1940     case 4:
1941         dwNumberOfPipes = VDENC_PIPE_FOUR_PIPE;
1942         break;
1943     default:
1944         dwNumberOfPipes = VDENC_PIPE_INVALID;
1945         ENCODE_ASSERT(false);
1946         break;
1947     }
1948 
1949     params.numPipe = dwNumberOfPipes;
1950 
1951     return MOS_STATUS_SUCCESS;
1952 }
1953 
MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE,Vp9VdencPkt)1954 MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE, Vp9VdencPkt)
1955 {
1956     ENCODE_FUNC_CALL();
1957 
1958     params.compressionFormatRaw   = m_surfacesParams[CODECHAL_HCP_SRC_SURFACE_ID].dwCompressionFormat;
1959     params.compressionFormatRecon = m_surfacesParams[CODECHAL_HCP_DECODED_SURFACE_ID].dwCompressionFormat;
1960 
1961     params.intraRowStoreScratchBuffer = const_cast<PMOS_RESOURCE>(&m_resVdencIntraRowStoreScratchBuffer);
1962     params.segmentMapStreamOutBuffer  = const_cast<PMOS_RESOURCE>(&m_resVdencSegmentMapStreamOut);
1963     params.segmentMapStreamInBuffer   = params.segmentMapStreamOutBuffer;
1964     params.pakObjCmdStreamOutBuffer   = m_resVdencPakObjCmdStreamOutBuffer;
1965 
1966     if (m_basicFeature->m_ref.DysRefFrameFlags() != DYS_REF_NONE && !m_resVdencPakObjCmdStreamOutBuffer)
1967     {
1968         params.pakObjCmdStreamOutBuffer = nullptr;
1969     }
1970 
1971     params.tileRowStoreBuffer               = const_cast<PMOS_RESOURCE>(&m_vdencTileRowStoreBuffer);
1972     params.cumulativeCuCountStreamOutBuffer = const_cast<PMOS_RESOURCE>(&m_vdencCumulativeCuCountStreamoutSurface);
1973 
1974     m_basicFeature->m_ref.MHW_SETPAR_F(VDENC_PIPE_BUF_ADDR_STATE)(params);
1975 
1976     return MOS_STATUS_SUCCESS;
1977 }
1978 
MHW_SETPAR_DECL_SRC(VDENC_CONTROL_STATE,Vp9VdencPkt)1979 MHW_SETPAR_DECL_SRC(VDENC_CONTROL_STATE, Vp9VdencPkt)
1980 {
1981     ENCODE_FUNC_CALL();
1982 
1983     params.vdencInitialization = true;
1984 
1985     return MOS_STATUS_SUCCESS;
1986 }
1987 
1988 
MHW_SETPAR_DECL_SRC(VD_PIPELINE_FLUSH,Vp9VdencPkt)1989 MHW_SETPAR_DECL_SRC(VD_PIPELINE_FLUSH, Vp9VdencPkt)
1990 {
1991     ENCODE_FUNC_CALL();
1992 
1993     ENCODE_CHK_NULL_RETURN(m_basicFeature);
1994 
1995     params.waitDoneMFX            = true;
1996     params.waitDoneVDCmdMsgParser = true;
1997 
1998     switch (m_flushCmd)
1999     {
2000     case waitVp9:
2001         params.waitDoneHEVC = true;
2002         params.flushHEVC    = true;
2003         break;
2004     case waitVdenc:
2005         if (m_basicFeature->m_lastPicInStream || m_basicFeature->m_lastPicInSeq)
2006         {
2007             params.waitDoneMFX = false;
2008         }
2009 
2010         params.waitDoneVDENC = true;
2011         params.flushVDENC    = true;
2012         params.flushHEVC     = true;
2013         break;
2014     case waitVp9Vdenc:
2015         params.waitDoneVDENC = true;
2016         params.flushVDENC    = true;
2017         params.flushHEVC     = true;
2018         break;
2019     }
2020 
2021     return MOS_STATUS_SUCCESS;
2022 }
2023 
2024 }  // namespace encode
2025