1 /*
2 * Copyright (c) 2019-2023, 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_av1_vdenc_packet.h
24 //! \brief    Defines the interface to adapt to AV1 VDENC packet
25 //!
26 
27 #ifndef __CODECHAL_AV1_VDENC_PACKET_H__
28 #define __CODECHAL_AV1_VDENC_PACKET_H__
29 
30 #include <vector>
31 #include "media_cmd_packet.h"
32 #include "encode_av1_vdenc_pipeline.h"
33 #include "encode_utils.h"
34 #include "encode_av1_basic_feature.h"
35 #include "encode_status_report.h"
36 #include "codec_def_encode_av1.h"
37 #include "mhw_vdbox_vdenc_itf.h"
38 #include "mhw_vdbox_avp_itf.h"
39 #include "mhw_mi_itf.h"
40 
41 namespace encode
42 {
43 #define CODECHAL_ENCODE_RECYCLED_BUFFER_NUM 6
44 #define CODECHAL_PAGE_SIZE 0x1000
45 #define CODECHAL_AV1_PAK_STREAMOUT_SIZE 0x500000  //size is accounted for 4Kx4K with all 8x8 CU,based on streamout0 and streamout1 requirements
46 //(4096*4096)/64 *16 (streamout0) + 1MB(streamout 1). there is scope to reduce streamout1 size. Need to check with HW team.
47 // 8K is just an estimation
48 
49 //!
50 //! \struct AtomicScratchBuffer
51 //! \brief  The sturct of Atomic Scratch Buffer
52 //!
53 struct AtomicScratchBufferAv1
54 {
55     PMOS_RESOURCE resAtomicScratchBuffer;  //!> Handle of eStatus buffer
56     uint32_t     *pData;                   //!> Pointer of the buffer of actual data
57     uint16_t      encodeUpdateIndex;       //!> used for VDBOX update encode status
58     uint16_t      tearDownIndex;           //!> Reserved for future extension
59     uint32_t      zeroValueOffset;         //!> Store the result of the ATOMIC_CMP
60     uint32_t      operand1Offset;          //!> Operand 1 of the ATOMIC_CMP
61     uint32_t      operand2Offset;          //!> Operand 2 of the ATOMIC_CMP
62     uint32_t      operand3Offset;          //!> Copy of the operand 1
63     uint32_t      size;                    //!> Size of the buffer
64     uint32_t      operandSetSize;          //!> Size of Operand set
65 };
66 
GetUseInterVsSkipSADWinner(uint32_t MrgCand8x8DepEn,uint32_t MrgCand16x16DepEn)67 inline uint32_t GetUseInterVsSkipSADWinner(uint32_t MrgCand8x8DepEn, uint32_t MrgCand16x16DepEn)
68 {
69     uint32_t useInterVsSkipSADWinner = 0;
70 
71     useInterVsSkipSADWinner =
72         ((MrgCand8x8DepEn & 1) << 0) | (1 << 1) |
73         ((MrgCand16x16DepEn & 1) << 2) | (1 << 3);
74 
75     if (MrgCand8x8DepEn == 3)
76     {
77         useInterVsSkipSADWinner = (1 << 3) | (MrgCand16x16DepEn & 0x1) << 2;
78     }
79     if (MrgCand16x16DepEn == 3)
80     {
81         useInterVsSkipSADWinner = (1 << 1) | (MrgCand8x8DepEn & 0x1);
82     }
83     if (MrgCand16x16DepEn == 3 && MrgCand8x8DepEn == 3)
84     {
85         useInterVsSkipSADWinner = 0;
86     }
87 
88     return useInterVsSkipSADWinner;
89 }
90 
91 class Av1VdencPkt : public CmdPacket, public MediaStatusReportObserver, public mhw::vdbox::vdenc::Itf::ParSetting, public mhw::vdbox::avp::Itf::ParSetting
92 {
93 public:
94     Av1VdencPkt(MediaPipeline* pipeline, MediaTask* task, CodechalHwInterfaceNext* hwInterface);
~Av1VdencPkt()95     virtual ~Av1VdencPkt() {}
96 
97     //!
98     //! \brief  Initialize the media packet, allocate required resources
99     //! \return MOS_STATUS
100     //!         MOS_STATUS_SUCCESS if success, else fail reason
101     //!
102     MOS_STATUS Init() override;
103 
104     //!
105     //! \brief  Prepare interal parameters, should be invoked for each frame
106     //! \param  [in] params
107     //!         Pointer to the input parameters
108     //! \return MOS_STATUS
109     //!         MOS_STATUS_SUCCESS if success, else fail reason
110     //!
111     MOS_STATUS Prepare() override;
112 
113     //!
114     //! \brief  Destroy the media packet and release the resources
115     //! \return MOS_STATUS
116     //!         MOS_STATUS_SUCCESS if success, else fail reason
117     //!
118     MOS_STATUS Destroy() override;
119 
120     virtual MOS_STATUS Submit(MOS_COMMAND_BUFFER *commandBuffer, uint8_t packetPhase = otherPacket) override;
121 
122     //!
123     //! \brief  One frame is completed
124     //! \param  [in] mfxStatus
125     //!         pointer to status buffer which for MFX
126     //! \param  [in] rcsStatus
127     //!         pointer to status buffer which for RCS
128     //! \param  [in, out] statusReport
129     //!         pointer of EncoderStatusReport
130     //! \return MOS_STATUS
131     //!         MOS_STATUS_SUCCESS if success, else fail reason
132     //!
133     virtual MOS_STATUS Completed(void *mfxStatus, void *rcsStatus, void *statusReport) override;
134 
135     //!
136     //! \brief  Calculate Command Size
137     //!
138     //! \param  [in, out] commandBufferSize
139     //!         requested size
140     //! \param  [in, out] requestedPatchListSize
141     //!         requested size
142     //! \return MOS_STATUS
143     //!         status
144     //!
145     MOS_STATUS CalculateCommandSize(
146         uint32_t &commandBufferSize,
147         uint32_t &requestedPatchListSize) override;
148 
149 #if (_DEBUG || _RELEASE_INTERNAL)
150     MOS_STATUS PerformSwStitch(
151         const EncodeReportTileData* tileReportData,
152         PakHwTileSizeRecord* tileStatusReport,
153         EncodeStatusReportData* statusReportData);
154 #endif
155 
156     //!
157     //! \brief  Get Packet Name
158     //! \return std::string
159     //!
GetPacketName()160     virtual std::string GetPacketName() override
161     {
162         return "AV1VDENC_PASS" + std::to_string((uint32_t)m_pipeline->GetCurrentPass());
163     }
164 
165 protected:
166 #if USE_CODECHAL_DEBUG_TOOL
167     //!
168     //! \brief  Dump input resources or infomation before submit
169     //! \return MOS_STATUS
170     //!         MOS_STATUS_SUCCESS if success, else fail reason
171     //!
172     virtual MOS_STATUS DumpInput();
173 
174     virtual MOS_STATUS DumpStatistics();
175 #endif
176 
177     virtual MOS_STATUS AllocateResources();
178 
179     virtual MOS_STATUS StartStatusReport(
180         uint32_t            srType,
181         MOS_COMMAND_BUFFER *cmdBuffer) override;
182 
183     virtual MOS_STATUS EndStatusReport(
184         uint32_t           srType,
185         MOS_COMMAND_BUFFER *cmdBuffer) override;
186 
187     virtual MOS_STATUS ReadAvpStatus(
188         MHW_VDBOX_NODE_IND vdboxIndex,
189         MediaStatusReport  *statusReport,
190         MOS_COMMAND_BUFFER &cmdBuffer);
191 
192     virtual MOS_STATUS AddOneTileCommands(
193         MOS_COMMAND_BUFFER  &cmdBuffer,
194         uint32_t            tileRow,
195         uint32_t            tileCol,
196         uint32_t            tileRowPass = 0) = 0;
197 
198     virtual MOS_STATUS EnsureAllCommandsExecuted(MOS_COMMAND_BUFFER &cmdBuffer) = 0;
199 
200     virtual MOS_STATUS RegisterPostCdef() = 0;
201 
202     virtual MOS_STATUS PatchTileLevelCommands(MOS_COMMAND_BUFFER &cmdBuffer, uint8_t packetPhase);
203 
204     MOS_STATUS AddCondBBEndFor2ndPass(MOS_COMMAND_BUFFER &cmdBuffer);
205 
206     virtual MOS_STATUS Construct3rdLevelBatch();
207 
208     virtual MOS_STATUS UpdateUserFeatureKey(PMOS_SURFACE surface);
209 
210     virtual MOS_STATUS UpdateStatusReport(uint32_t srType, MOS_COMMAND_BUFFER *cmdBuffer) override;
211 
212     //!
213     //! \brief  Calculate Command Buffer Size
214     //!
215     //! \return uint32_t
216     //!         Command buffer size calculated
217     //!
218     virtual uint32_t CalculateCommandBufferSize();
219 
220     //!
221     //! \brief  Calculate Patch List Size
222     //!
223     //! \return uint32_t
224     //!         Patchlist size calculated
225     //!
226     virtual uint32_t CalculatePatchListSize();
227 
228     //!
229     //! \brief    Calculate Vdenc Commands Size
230     //!
231     //! \return   MOS_STATUS
232     //!           MOS_STATUS_SUCCESS if success
233     //!
234     virtual MOS_STATUS CalculateVdencCommandsSize();
235 
236     //!
237     //! \brief    Calculate avp picture state command size
238     //!
239     //! \return   MOS_STATUS
240     //!           MOS_STATUS_SUCCESS if success, else fail reason
241     //!
242     virtual MOS_STATUS CalculateAvpPictureStateCommandSize(uint32_t * commandsSize, uint32_t * patchListSize);
243 
244     //!
245     //! \brief    get  SliceStatesSize and SlicePatchListSize,
246     //!
247     //! \return   MOS_STATUS
248     //!           MOS_STATUS_SUCCESS if success, else fail reason
249     //!
250     virtual MOS_STATUS CalculateAvpCommandsSize();
251     virtual MOS_STATUS AddPictureVdencCommands(MOS_COMMAND_BUFFER &cmdBuffer);
252     virtual MOS_STATUS PatchPictureLevelCommands(const uint8_t &packetPhase, MOS_COMMAND_BUFFER &cmdBuffer);
253 
254 #if USE_CODECHAL_DEBUG_TOOL
255     //! \brief    Dump the output resources in status report callback function
256     //!
257     //! \param    [in] encodeStatusMfx
258     //!           Pointer to encoder status for vdbox
259     //! \param    [in] statusReportData
260     //!           Pointer to encoder status report data
261     //!
262     //! \return   MOS_STATUS
263     //!           MOS_STATUS_SUCCESS if success, else fail reason
264     //!
265     MOS_STATUS DumpResources(
266         EncodeStatusMfx        *encodeStatusMfx,
267         EncodeStatusReportData *statusReportData);
268 
269 #endif  // USE_CODECHAL_DEBUG_TOOL
270 
271     Av1VdencPipeline *m_pipeline = nullptr;
272 
273     // Interfaces
274     EncodeAllocator                 *m_allocator        = nullptr;
275     CodechalHwInterfaceNext         *m_hwInterface      = nullptr;
276     CodechalHwInterfaceNext         *m_hwInterfaceNext  = nullptr;
277     EncodeMemComp                   *m_mmcState         = nullptr;
278     Av1BasicFeature                 *m_basicFeature     = nullptr;              //!< Encode parameters used in each frame
279     MHW_VDBOX_NODE_IND              m_vdboxIndex        = MHW_VDBOX_NODE_1;
280     uint32_t                        m_mvOffset          = 0;                    //!< MV data offset, in 64 byte
281     std::shared_ptr<mhw::vdbox::vdenc::Itf>   m_vdencItf           = nullptr;
282     std::shared_ptr<mhw::vdbox::avp::Itf>     m_avpItf             = nullptr;
283     const CODEC_AV1_ENCODE_PICTURE_PARAMS    *m_av1PicParams       = nullptr;   //!< Pointer to picture parameter
284     const CODEC_AV1_ENCODE_SEQUENCE_PARAMS   *m_av1SeqParams       = nullptr;   //!< Pointer to sequence parameter
285     const PCODECHAL_NAL_UNIT_PARAMS          *m_nalUnitParams      = nullptr;   //!< Pointer to NAL unit parameters
286     uint8_t                                   m_prevFrameType      = keyFrame;  //!< Previous frame type
287 
288     std::shared_ptr<MediaFeatureManager::ManagerLite> m_featureManager = nullptr;
289 
290     mutable uint8_t m_curAvpSurfStateId = 0;
291 
292     AtomicScratchBufferAv1 m_atomicScratchBuf = {};  //!< Stores atomic operands and result
293 
294     bool m_userFeatureUpdated_post_cdef                 = false;    //!< Inidate if mmc user feature key for post cdef is updated
295     bool m_vdencPakObjCmdStreamOutEnabled               = false;    //!< Pakobj stream out enable flag
296     PMOS_RESOURCE m_resCumulativeCuCountStreamoutBuffer = nullptr;  //!< Cumulative CU count stream out buffer
297     PMOS_RESOURCE m_vdencIntraRowStoreScratch           = nullptr;
298     PMOS_RESOURCE m_vdencTileRowStoreBuffer             = nullptr;  //!< Tile row store buffer
299     PMOS_RESOURCE m_resVDEncPakObjCmdStreamOutBuffer    = nullptr;  //!< Resource of Vdenc Pak object command stream out buffer
300     PMOS_RESOURCE m_resVDEncStatsBuffer                 = nullptr;  //!< Resource of Vdenc status buffer
301     PMOS_RESOURCE m_resVDEncCuObjStreamOutBuffer        = nullptr;  //!< Resource of Vdenc Cu object stream out buffer
302 
303     bool     m_usePatchList                = false;  //!< Use Ptach List or not
304     uint32_t m_pictureStatesSize           = 0;  //!< Picture states size
305     uint32_t m_picturePatchListSize        = 0;  //!< Picture patch list size
306     uint32_t m_tileStatesSize              = 0;  //!< Slice states size
307     uint32_t m_tilePatchListSize           = 0;  //!< Slice patch list size
308 
309     MOS_STATUS SetPipeBufAddr(
310         PMHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams,
311         MHW_VDBOX_SURFACE_PARAMS &      srcSurfaceParams,
312         MHW_VDBOX_SURFACE_PARAMS &      reconSurfaceParams);
313 
314     MOS_STATUS SetSurfaceState(
315         PMHW_VDBOX_SURFACE_PARAMS surfaceStateParams);
316 
317     void SetPerfTag();
318     MOS_STATUS AddForceWakeup(MOS_COMMAND_BUFFER &cmdBuffer);
319     MOS_STATUS SendPrologCmds(MOS_COMMAND_BUFFER &cmdBuffer);
320     MOS_STATUS SetRowstoreCachingOffsets();
321 
322     virtual void UpdateParameters();
323 
324     MOS_STATUS ReadPakMmioRegisters(PMOS_COMMAND_BUFFER cmdBuf, bool firstTile);
325 
326     MOS_STATUS ReadPakMmioRegistersAtomic(PMOS_COMMAND_BUFFER cmdBuf);
327 
328     MHW_SETPAR_DECL_HDR(VD_PIPELINE_FLUSH);
329 
330     MHW_SETPAR_DECL_HDR(VDENC_PIPE_MODE_SELECT);
331 
332     MHW_SETPAR_DECL_HDR(VDENC_PIPE_BUF_ADDR_STATE);
333 
334     MHW_SETPAR_DECL_HDR(VDENC_HEVC_VP9_TILE_SLICE_STATE);
335 
336     MHW_SETPAR_DECL_HDR(AVP_SURFACE_STATE);
337 
338     MHW_SETPAR_DECL_HDR(AVP_PIPE_MODE_SELECT);
339 
340     MHW_SETPAR_DECL_HDR(AVP_PIPE_BUF_ADDR_STATE);
341 
342     MHW_SETPAR_DECL_HDR(AVP_IND_OBJ_BASE_ADDR_STATE);
343 
344     MHW_SETPAR_DECL_HDR(AVP_PIC_STATE);
345 
346     MHW_SETPAR_DECL_HDR(AVP_TILE_CODING);
347 
348     virtual MOS_STATUS AddAllCmds_AVP_SURFACE_STATE(PMOS_COMMAND_BUFFER cmdBuffer) const;
349 
350     virtual MOS_STATUS AddAllCmds_AVP_PAK_INSERT_OBJECT(PMOS_COMMAND_BUFFER cmdBuffer) const;
351 
352     virtual MOS_STATUS AddAllCmds_AVP_PIPE_MODE_SELECT(PMOS_COMMAND_BUFFER cmdBuffer) const;
353 
354     virtual MOS_STATUS AddAllCmds_AVP_SEGMENT_STATE(PMOS_COMMAND_BUFFER cmdBuffer) const;
355 
356     virtual MOS_STATUS GetVdencStateCommandsDataSize(uint32_t *commandsSize, uint32_t *patchListSize) const;
357 
358     virtual MOS_STATUS GetVdencPrimitiveCommandsDataSize(uint32_t *commandsSize, uint32_t *patchListSize) const;
359 
360     virtual MOS_STATUS GetAvpPrimitiveCommandsDataSize(uint32_t *commandsSize, uint32_t *patchListSize) const;
361 
362     virtual MOS_STATUS PrepareHWMetaData(MOS_COMMAND_BUFFER *cmdBuffer);
363 
364     virtual MOS_STATUS PrepareHWMetaDataFromStreamout(MOS_COMMAND_BUFFER *cmdBuffer, const MetaDataOffset resourceOffset, const AV1MetaDataOffset AV1ResourceOffset);
365 
366     virtual MOS_STATUS PrepareHWMetaDataFromRegister(MOS_COMMAND_BUFFER *cmdBuffer, const MetaDataOffset resourceOffset);
367 
368     virtual MOS_STATUS PrepareHWMetaDataFromDriver(MOS_COMMAND_BUFFER *cmdBuffer, const MetaDataOffset resourceOffset, const AV1MetaDataOffset AV1ResourceOffset);
369 
370     virtual MOS_STATUS readBRCMetaDataFromSLBB(MOS_COMMAND_BUFFER *cmdBuffer, PMOS_RESOURCE presDst, uint32_t dstOffset, PMOS_RESOURCE presSrc, uint32_t srcOffset, uint32_t significantBits);
371 
372     virtual MOS_STATUS PrepareHWMetaDataFromStreamoutTileLevel(MOS_COMMAND_BUFFER *cmdBuffer, uint32_t tileCol, uint32_t tileRow);
373 
374     inline MOS_STATUS CalAtomic(PMOS_RESOURCE presDst, uint32_t dstOffset, PMOS_RESOURCE presSrc, uint32_t srcOffset, mhw::mi::MHW_COMMON_MI_ATOMIC_OPCODE opCode, MOS_COMMAND_BUFFER *cmdBuffer);
375 
376     MEDIA_CLASS_DEFINE_END(encode__Av1VdencPkt)
377 };
378 
379 }  // namespace encode
380 #endif
381