1 /*
2 * Copyright (c) 2021-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     decode_huc_s2l_packet.cpp
24 //! \brief    Defines the interface for huc S2L packet
25 //!
26 #include "decode_huc_s2l_packet.h"
27 #include "mhw_vdbox.h"
28 
29 namespace decode {
30 
Init()31     MOS_STATUS HucS2lPkt::Init()
32     {
33         DECODE_FUNC_CALL();
34         DECODE_CHK_NULL(m_hevcPipeline);
35 
36         DECODE_CHK_STATUS(DecodeHucBasic::Init());
37 
38         m_hevcBasicFeature = dynamic_cast<HevcBasicFeature*>(m_basicFeature);
39         DECODE_CHK_NULL(m_hevcBasicFeature);
40 
41         DECODE_CHK_STATUS(m_statusReport->RegistObserver(this));
42 
43         MHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams;
44         stateCmdSizeParams.bShortFormat = true;
45         DECODE_CHK_STATUS(m_hwInterface->GetHucStateCommandSize(m_hevcBasicFeature->m_mode, &m_pictureStatesSize,
46                                                                  &m_picturePatchListSize, &stateCmdSizeParams));
47         uint32_t cpCmdsize        = 0;
48         uint32_t cpPatchListSize  = 0;
49         m_hwInterface->GetCpInterface()->GetCpSliceLevelCmdSize(cpCmdsize, cpPatchListSize);
50         m_sliceStatesSize += cpCmdsize;
51         m_slicePatchListSize += cpPatchListSize;
52 
53         if (m_s2lControlTempMVRegionBuffer == nullptr)
54         {
55             m_s2lControlTempMVRegionBuffer = m_allocator->AllocateBuffer(
56                 sizeof(uint32_t), "S2lControlTempMVRegionBuffer", resourceInternalReadWriteCache, notLockableVideoMem);
57             DECODE_CHK_NULL(m_s2lControlTempMVRegionBuffer);
58         }
59 
60         return MOS_STATUS_SUCCESS;
61     }
62 
Prepare()63     MOS_STATUS HucS2lPkt::Prepare()
64     {
65         DECODE_FUNC_CALL();
66 
67         m_hevcPicParams = m_hevcBasicFeature->m_hevcPicParams;
68         DECODE_CHK_NULL(m_hevcPicParams);
69         m_hevcSliceParams = m_hevcBasicFeature->m_hevcSliceParams;
70         DECODE_CHK_NULL(m_hevcSliceParams);
71 
72         m_hevcRextPicParams = m_hevcBasicFeature->m_hevcRextPicParams;
73         m_hevcSccPicParams  = m_hevcBasicFeature->m_hevcSccPicParams;
74 
75         return MOS_STATUS_SUCCESS;
76     }
77 
Destroy()78     MOS_STATUS HucS2lPkt::Destroy()
79     {
80         return FreeResource();
81     }
82 
FreeResource()83     MOS_STATUS HucS2lPkt::FreeResource()
84     {
85         DECODE_FUNC_CALL();
86 
87         if (m_allocator != nullptr)
88         {
89             DECODE_CHK_STATUS(m_allocator->Destroy(m_s2lControlTempMVRegionBuffer));
90         }
91 
92         return MOS_STATUS_SUCCESS;
93     }
94 
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)95     MOS_STATUS HucS2lPkt::CalculateCommandSize(uint32_t &commandBufferSize, uint32_t &requestedPatchListSize)
96     {
97         DECODE_FUNC_CALL();
98 
99         commandBufferSize      = CalculateCommandBufferSize();
100         requestedPatchListSize = CalculatePatchListSize();
101 
102         return MOS_STATUS_SUCCESS;
103     }
104 
CalculateCommandBufferSize()105     uint32_t HucS2lPkt::CalculateCommandBufferSize()
106     {
107         DECODE_FUNC_CALL();
108 
109         uint32_t commandBufferSize = m_pictureStatesSize +
110                                      m_sliceStatesSize * (m_hevcBasicFeature->m_numSlices+1);
111 
112         return (commandBufferSize + COMMAND_BUFFER_RESERVED_SPACE);
113     }
114 
CalculatePatchListSize()115     uint32_t HucS2lPkt::CalculatePatchListSize()
116     {
117         DECODE_FUNC_CALL();
118 
119         if (!m_osInterface->bUsesPatchList)
120         {
121             return 0;
122         }
123 
124         uint32_t requestedPatchListSize = m_picturePatchListSize +
125                                           m_slicePatchListSize * (m_hevcBasicFeature->m_numSlices+1);
126 
127         return requestedPatchListSize;
128     }
129 
SetHucDmemPictureBss(HucHevcS2lPicBss & hucHevcS2LPicBss)130     MOS_STATUS HucS2lPkt::SetHucDmemPictureBss(HucHevcS2lPicBss &hucHevcS2LPicBss)
131     {
132         DECODE_FUNC_CALL();
133 
134         hucHevcS2LPicBss.pic_width_in_min_cbs_y                       = m_hevcPicParams->PicWidthInMinCbsY;
135         hucHevcS2LPicBss.pic_height_in_min_cbs_y                      = m_hevcPicParams->PicHeightInMinCbsY;
136         hucHevcS2LPicBss.log2_min_luma_coding_block_size_minus3       = m_hevcPicParams->log2_min_luma_coding_block_size_minus3;
137         hucHevcS2LPicBss.log2_diff_max_min_luma_coding_block_size     = m_hevcPicParams->log2_diff_max_min_luma_coding_block_size;
138         hucHevcS2LPicBss.chroma_format_idc                            = m_hevcPicParams->chroma_format_idc;
139         hucHevcS2LPicBss.separate_colour_plane_flag                   = m_hevcPicParams->separate_colour_plane_flag;
140         hucHevcS2LPicBss.bit_depth_luma_minus8                        = m_hevcPicParams->bit_depth_luma_minus8;
141         hucHevcS2LPicBss.bit_depth_chroma_minus8                      = m_hevcPicParams->bit_depth_chroma_minus8;
142         hucHevcS2LPicBss.log2_max_pic_order_cnt_lsb_minus4            = m_hevcPicParams->log2_max_pic_order_cnt_lsb_minus4;
143         hucHevcS2LPicBss.sample_adaptive_offset_enabled_flag          = m_hevcPicParams->sample_adaptive_offset_enabled_flag;
144         hucHevcS2LPicBss.num_short_term_ref_pic_sets                  = m_hevcPicParams->num_short_term_ref_pic_sets;
145         hucHevcS2LPicBss.long_term_ref_pics_present_flag              = m_hevcPicParams->long_term_ref_pics_present_flag;
146         hucHevcS2LPicBss.num_long_term_ref_pics_sps                   = m_hevcPicParams->num_long_term_ref_pic_sps;
147         hucHevcS2LPicBss.sps_temporal_mvp_enable_flag                 = m_hevcPicParams->sps_temporal_mvp_enabled_flag;
148         hucHevcS2LPicBss.num_ref_idx_l0_default_active_minus1         = m_hevcPicParams->num_ref_idx_l0_default_active_minus1;
149         hucHevcS2LPicBss.num_ref_idx_l1_default_active_minus1         = m_hevcPicParams->num_ref_idx_l1_default_active_minus1;
150         hucHevcS2LPicBss.pic_init_qp_minus26                          = m_hevcPicParams->init_qp_minus26;
151         hucHevcS2LPicBss.dependent_slice_segments_enabled_flag        = m_hevcPicParams->dependent_slice_segments_enabled_flag;
152         hucHevcS2LPicBss.cabac_init_present_flag                      = m_hevcPicParams->cabac_init_present_flag;
153         hucHevcS2LPicBss.pps_slice_chroma_qp_offsets_present_flag     = m_hevcPicParams->pps_slice_chroma_qp_offsets_present_flag;
154         hucHevcS2LPicBss.weighted_pred_flag                           = m_hevcPicParams->weighted_pred_flag;
155         hucHevcS2LPicBss.weighted_bipred_flag                         = m_hevcPicParams->weighted_bipred_flag;
156         hucHevcS2LPicBss.output_flag_present_flag                     = m_hevcPicParams->output_flag_present_flag;
157         hucHevcS2LPicBss.tiles_enabled_flag                           = m_hevcPicParams->tiles_enabled_flag;
158         hucHevcS2LPicBss.entropy_coding_sync_enabled_flag             = m_hevcPicParams->entropy_coding_sync_enabled_flag;
159         hucHevcS2LPicBss.loop_filter_across_slices_enabled_flag       = m_hevcPicParams->pps_loop_filter_across_slices_enabled_flag;
160         hucHevcS2LPicBss.deblocking_filter_override_enabled_flag      = m_hevcPicParams->deblocking_filter_override_enabled_flag;
161         hucHevcS2LPicBss.pic_disable_deblocking_filter_flag           = m_hevcPicParams->pps_deblocking_filter_disabled_flag;
162         hucHevcS2LPicBss.lists_modification_present_flag              = m_hevcPicParams->lists_modification_present_flag;
163         hucHevcS2LPicBss.slice_segment_header_extension_present_flag  = m_hevcPicParams->slice_segment_header_extension_present_flag;
164         hucHevcS2LPicBss.high_precision_offsets_enabled_flag          = 0;
165         hucHevcS2LPicBss.chroma_qp_offset_list_enabled_flag           = 0;
166 
167         hucHevcS2LPicBss.CurrPicOrderCntVal = m_hevcPicParams->CurrPicOrderCntVal;
168         for (uint32_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
169         {
170             hucHevcS2LPicBss.PicOrderCntValList[i] = m_hevcPicParams->PicOrderCntValList[i];
171         }
172 
173         for (uint32_t i = 0; i < 8; i++)
174         {
175             hucHevcS2LPicBss.RefPicSetStCurrBefore[i] = m_hevcPicParams->RefPicSetStCurrBefore[i];
176             hucHevcS2LPicBss.RefPicSetStCurrAfter[i]  = m_hevcPicParams->RefPicSetStCurrAfter[i];
177             hucHevcS2LPicBss.RefPicSetLtCurr[i]       = m_hevcPicParams->RefPicSetLtCurr[i];
178         }
179 
180         hucHevcS2LPicBss.RefFieldPicFlag      = m_hevcPicParams->RefFieldPicFlag;
181         hucHevcS2LPicBss.RefBottomFieldFlag   = (uint8_t)m_hevcPicParams->RefBottomFieldFlag;
182         hucHevcS2LPicBss.pps_beta_offset_div2 = m_hevcPicParams->pps_beta_offset_div2;
183         hucHevcS2LPicBss.pps_tc_offset_div2   = m_hevcPicParams->pps_tc_offset_div2;
184         hucHevcS2LPicBss.StRPSBits            = m_hevcPicParams->wNumBitsForShortTermRPSInSlice;
185 
186         if (m_hevcPicParams->tiles_enabled_flag)
187         {
188             hucHevcS2LPicBss.num_tile_columns_minus1 = m_hevcPicParams->num_tile_columns_minus1;
189             hucHevcS2LPicBss.num_tile_rows_minus1    = m_hevcPicParams->num_tile_rows_minus1;
190 
191             const uint16_t *tileColWidth = m_hevcBasicFeature->m_tileCoding.GetTileColWidth();
192             for (auto i = 0; i < HEVC_NUM_MAX_TILE_COLUMN; i++)
193             {
194                 hucHevcS2LPicBss.column_width[i] = tileColWidth[i];
195             }
196 
197             const uint16_t *tileRowHeight = m_hevcBasicFeature->m_tileCoding.GetTileRowHeight();
198             for (auto i = 0; i < HEVC_NUM_MAX_TILE_ROW; i++)
199             {
200                 hucHevcS2LPicBss.row_height[i] = tileRowHeight[i];
201             }
202         }
203 
204         hucHevcS2LPicBss.NumSlices                   = (uint16_t)m_hevcBasicFeature->m_numSlices;
205         hucHevcS2LPicBss.num_extra_slice_header_bits = m_hevcPicParams->num_extra_slice_header_bits;
206 
207         int8_t *refIdxMapping = m_hevcBasicFeature->m_refFrames.m_refIdxMapping;
208         for (auto i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
209         {
210             hucHevcS2LPicBss.RefIdxMapping[i] = refIdxMapping[i];
211         }
212         if(m_decodecp)
213         {
214             DECODE_CHK_STATUS(m_decodecp->SetHucDmemS2LPicBss(&hucHevcS2LPicBss.reserve, &(m_hevcBasicFeature->m_resDataBuffer.OsResource)));
215         }
216         else
217         {
218             hucHevcS2LPicBss.reserve.reserve_0 = 0;
219             hucHevcS2LPicBss.reserve.reserve_1 = 0;
220             hucHevcS2LPicBss.reserve.reserve_2 = 0;
221             hucHevcS2LPicBss.reserve.reserve_3 = 0;
222         }
223         return MOS_STATUS_SUCCESS;
224     }
225 
SetHucDmemSliceBss(HucHevcS2lSliceBss (& hucHevcS2LSliceBss)[CODECHAL_HEVC_MAX_NUM_SLICES_LVL_6])226     MOS_STATUS HucS2lPkt::SetHucDmemSliceBss(
227         HucHevcS2lSliceBss (&hucHevcS2LSliceBss)[CODECHAL_HEVC_MAX_NUM_SLICES_LVL_6])
228     {
229         DECODE_FUNC_CALL();
230 
231         for (uint32_t i = 0; i < m_hevcBasicFeature->m_numSlices && i < CODECHAL_HEVC_MAX_NUM_SLICES_LVL_6; i++)
232         {
233             hucHevcS2LSliceBss[i].BSNALunitDataLocation = m_hevcSliceParams[i].slice_data_offset;
234             hucHevcS2LSliceBss[i].SliceBytesInBuffer    = m_hevcSliceParams[i].slice_data_size;
235             if(m_decodecp)
236             {
237                 DECODE_CHK_STATUS(m_decodecp->SetHucDmemS2LSliceBss(&hucHevcS2LSliceBss[i].reserve, i, m_hevcSliceParams[i].slice_data_size, m_hevcSliceParams[i].slice_data_offset));
238             }
239         }
240         return MOS_STATUS_SUCCESS;
241     }
242 
AddHucCpState(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t index,CODEC_HEVC_SLICE_PARAMS & sliceParams)243     MOS_STATUS HucS2lPkt::AddHucCpState(MOS_COMMAND_BUFFER &cmdBuffer, uint32_t index, CODEC_HEVC_SLICE_PARAMS &sliceParams)
244     {
245         if(m_decodecp)
246         {
247             DECODE_CHK_STATUS(m_decodecp->AddHucState(&cmdBuffer,
248                 &(m_hevcBasicFeature->m_resDataBuffer.OsResource),
249                 sliceParams.slice_data_size,
250                 sliceParams.slice_data_offset,
251                 index));
252         }
253         return MOS_STATUS_SUCCESS;
254     }
255 
AddCmd_HUC_IMEM_STATE(MOS_COMMAND_BUFFER & cmdBuffer)256     MOS_STATUS HucS2lPkt::AddCmd_HUC_IMEM_STATE(MOS_COMMAND_BUFFER &cmdBuffer)
257     {
258           DECODE_FUNC_CALL();
259           auto &par = m_hucItf->MHW_GETPAR_F(HUC_IMEM_STATE)();
260           par                  = {};
261           par.kernelDescriptor = m_vdboxHucHevcS2lKernelDescriptor;
262           DECODE_CHK_STATUS(m_hucItf->MHW_ADDCMD_F(HUC_IMEM_STATE)(&cmdBuffer));
263 
264           auto &mfxWaitParams               = m_miItf->MHW_GETPAR_F(MFX_WAIT)();
265           mfxWaitParams                     = {};
266           mfxWaitParams.iStallVdboxPipeline = true;
267           DECODE_CHK_STATUS((m_miItf->MHW_ADDCMD_F(MFX_WAIT)(&cmdBuffer)));
268 
269           return MOS_STATUS_SUCCESS;
270     }
271 
AddCmd_HUC_PIPE_MODE_SELECT(MOS_COMMAND_BUFFER & cmdBuffer)272     MOS_STATUS HucS2lPkt::AddCmd_HUC_PIPE_MODE_SELECT(MOS_COMMAND_BUFFER &cmdBuffer)
273     {
274           DECODE_FUNC_CALL();
275           //for gen 11+, we need to add MFX wait for both KIN and VRT before and after HUC Pipemode select...
276           auto &mfxWaitParams               = m_miItf->MHW_GETPAR_F(MFX_WAIT)();
277           mfxWaitParams                     = {};
278           mfxWaitParams.iStallVdboxPipeline = true;
279           DECODE_CHK_STATUS((m_miItf->MHW_ADDCMD_F(MFX_WAIT)(&cmdBuffer)));
280 
281           auto &par = m_hucItf->MHW_GETPAR_F(HUC_PIPE_MODE_SELECT)();
282           par                  = {};
283           par.streamOutEnabled = false;
284           DECODE_CHK_STATUS(m_hucItf->MHW_ADDCMD_F(HUC_PIPE_MODE_SELECT)(&cmdBuffer));
285 
286           mfxWaitParams                     = {};
287           mfxWaitParams.iStallVdboxPipeline = true;
288           DECODE_CHK_STATUS((m_miItf->MHW_ADDCMD_F(MFX_WAIT)(&cmdBuffer)));
289           return MOS_STATUS_SUCCESS;
290     }
291 
MHW_SETPAR_DECL_SRC(HUC_IND_OBJ_BASE_ADDR_STATE,HucS2lPkt)292     MHW_SETPAR_DECL_SRC(HUC_IND_OBJ_BASE_ADDR_STATE, HucS2lPkt)
293     {
294         DECODE_FUNC_CALL();
295 
296         params.DataSize   = m_hevcBasicFeature->m_dataSize;
297         params.DataOffset = m_hevcBasicFeature->m_dataOffset;
298         params.DataBuffer = &(m_hevcBasicFeature->m_resDataBuffer.OsResource);
299         return MOS_STATUS_SUCCESS;
300     }
301 
MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE,HucS2lPkt)302     MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE, HucS2lPkt)
303     {
304         DECODE_FUNC_CALL();
305 
306         PMHW_BATCH_BUFFER batchBuffer = m_hevcPipeline->GetSliceLvlCmdBuffer();
307         DECODE_CHK_NULL(batchBuffer);
308         params.regionParams[0].presRegion = &batchBuffer->OsResource;
309         params.regionParams[0].isWritable = true;
310 
311         PMOS_BUFFER regionBuffer = m_s2lControlTempMVRegionBuffer;
312         DECODE_CHK_NULL(regionBuffer);
313         params.regionParams[1].presRegion = &regionBuffer->OsResource;
314         params.regionParams[1].isWritable = true;
315 
316         return MOS_STATUS_SUCCESS;
317     }
318 
MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE,HucS2lPkt)319     MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE, HucS2lPkt)
320     {
321         DECODE_FUNC_CALL();
322 
323         params.hucDataSource = &m_s2lDmemBuffer->OsResource;
324         params.dataLength    = MOS_ALIGN_CEIL(m_dmemTransferSize, CODECHAL_CACHELINE_SIZE);
325         params.dmemOffset    = HUC_DMEM_OFFSET_RTOS_GEMS;
326         return MOS_STATUS_SUCCESS;
327     }
328 
AddCmd_HUC_STREAM_OBJECT(MOS_COMMAND_BUFFER & cmdBuffer,CODEC_HEVC_SLICE_PARAMS sliceParams)329     MOS_STATUS HucS2lPkt::AddCmd_HUC_STREAM_OBJECT(MOS_COMMAND_BUFFER &cmdBuffer, CODEC_HEVC_SLICE_PARAMS sliceParams)
330     {
331         DECODE_FUNC_CALL();
332 
333         auto &par                        = m_hucItf->MHW_GETPAR_F(HUC_STREAM_OBJECT)();
334         par                              = {};
335         par.IndirectStreamInDataLength   = sliceParams.slice_data_size;
336         par.StreamOut                    = 0;
337         par.IndirectStreamInStartAddress = sliceParams.slice_data_offset;
338         par.HucProcessing                = true;
339 
340         par.HucBitstreamEnable             = 1;
341         par.EmulationPreventionByteRemoval = 1;
342         par.StartCodeSearchEngine          = 1;
343         par.StartCodeByte0                 = 0;
344         par.StartCodeByte1                 = 0;
345         par.StartCodeByte2                 = 1;
346 
347         DECODE_CHK_STATUS(m_hucItf->MHW_ADDCMD_F(HUC_STREAM_OBJECT)(&cmdBuffer));
348 
349         return MOS_STATUS_SUCCESS;
350     }
351 
AddCmd_HUC_START(MOS_COMMAND_BUFFER & cmdBuffer,bool laststreamobject)352     MOS_STATUS HucS2lPkt::AddCmd_HUC_START(MOS_COMMAND_BUFFER &cmdBuffer, bool laststreamobject)
353     {
354         DECODE_FUNC_CALL();
355         auto &par = m_hucItf->MHW_GETPAR_F(HUC_START)();
356         par                  = {};
357         par.lastStreamObject = laststreamobject;
358         DECODE_CHK_STATUS(m_hucItf->MHW_ADDCMD_F(HUC_START)(&cmdBuffer));
359 
360         return MOS_STATUS_SUCCESS;
361     }
362 
363 
364 #if USE_CODECHAL_DEBUG_TOOL
DumpHucS2l()365     MOS_STATUS HucS2lPkt::DumpHucS2l()
366     {
367         DECODE_FUNC_CALL();
368 
369         int32_t currentPass = m_pipeline->GetCurrentPass();
370 
371         CodechalDebugInterface *debugInterface = m_pipeline->GetDebugInterface();
372         DECODE_CHK_NULL(debugInterface);
373 
374         DECODE_CHK_STATUS(debugInterface->DumpHucDmem(
375             &m_s2lDmemBuffer->OsResource,
376             m_dmemTransferSize,
377             currentPass,
378             hucRegionDumpDefault));
379 
380         return MOS_STATUS_SUCCESS;
381     }
382 #endif
383 }
384