1 /*
2 * Copyright (c) 2020-2021, 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_avc_huc_brc_init_packet.cpp
24 //! \brief    Defines the interface for avc huc brc init/reset packet
25 //!
26 
27 #include "encode_avc_huc_brc_init_packet.h"
28 #include "encode_avc_vdenc_const_settings.h"
29 #include "encode_avc_brc.h"
30 #include "media_avc_feature_defs.h"
31 
32 namespace encode {
33 
Init()34 MOS_STATUS AvcHucBrcInitPkt::Init()
35 {
36     ENCODE_FUNC_CALL();
37 
38     ENCODE_CHK_STATUS_RETURN(EncodeHucPkt::Init());
39 
40     ENCODE_CHK_NULL_RETURN(m_featureManager);
41     m_basicFeature = dynamic_cast<AvcBasicFeature *>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
42     ENCODE_CHK_NULL_RETURN(m_basicFeature);
43 
44     return MOS_STATUS_SUCCESS;
45 }
46 
DumpOutput()47 MOS_STATUS AvcHucBrcInitPkt::DumpOutput()
48 {
49     ENCODE_FUNC_CALL();
50 
51 #if USE_CODECHAL_DEBUG_TOOL
52     ENCODE_CHK_STATUS_RETURN(DumpHucBrcInit(false));
53 #endif
54 
55     return MOS_STATUS_SUCCESS;
56 }
57 
AllocateResources()58 MOS_STATUS AvcHucBrcInitPkt::AllocateResources()
59 {
60     ENCODE_FUNC_CALL();
61 
62     ENCODE_CHK_STATUS_RETURN(EncodeHucPkt::AllocateResources());
63 
64     // initiate allocation parameters and lock flags
65     MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
66     MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
67     allocParamsForBufferLinear.Type     = MOS_GFXRES_BUFFER;
68     allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
69     allocParamsForBufferLinear.Format   = Format_Buffer;
70     allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_WRITE;
71 
72     allocParamsForBufferLinear.dwBytes  = MOS_ALIGN_CEIL(m_vdencBrcInitDmemBufferSize, CODECHAL_CACHELINE_SIZE);
73     allocParamsForBufferLinear.pBufName = "VDENC BrcInit DmemBuffer";
74 
75     for (uint32_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
76     {
77         PMOS_RESOURCE allocatedbuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
78         ENCODE_CHK_NULL_RETURN(allocatedbuffer);
79         m_vdencBrcInitDmemBuffer[i] = allocatedbuffer;
80     }
81 
82     return MOS_STATUS_SUCCESS;
83 }
84 
Submit(MOS_COMMAND_BUFFER * commandBuffer,uint8_t packetPhase)85 MOS_STATUS AvcHucBrcInitPkt::Submit(MOS_COMMAND_BUFFER *commandBuffer, uint8_t packetPhase)
86 {
87     ENCODE_FUNC_CALL();
88 
89     bool firstTaskInPhase = packetPhase & firstPacket;
90     bool requestProlog = false;
91 
92     if (!m_pipeline->IsSingleTaskPhaseSupported() || firstTaskInPhase)
93     {
94         // Send command buffer header at the beginning (OS dependent)
95         requestProlog = true;
96     }
97 
98     auto brcFeature = dynamic_cast<AvcEncodeBRC *>(m_featureManager->GetFeature(AvcFeatureIDs::avcBrcFeature));
99     ENCODE_CHK_NULL_RETURN(brcFeature);
100 
101     ENCODE_CHK_STATUS_RETURN(brcFeature->SaveHucStatus2Buffer(m_resHucStatus2Buffer));
102 
103     SetPerfTag(CODECHAL_ENCODE_PERFTAG_CALL_BRC_INIT_RESET, (uint16_t)m_basicFeature->m_mode, m_basicFeature->m_pictureCodingType);
104     ENCODE_CHK_STATUS_RETURN(Execute(commandBuffer, true, requestProlog, BRC_INIT));
105 
106     CODECHAL_DEBUG_TOOL(
107         ENCODE_CHK_STATUS_RETURN(DumpHucBrcInit(true));)
108 
109     return MOS_STATUS_SUCCESS;
110 }
111 
AddForceWakeup(MOS_COMMAND_BUFFER & cmdBuffer)112 MOS_STATUS AvcHucBrcInitPkt::AddForceWakeup(MOS_COMMAND_BUFFER &cmdBuffer)
113 {
114     ENCODE_FUNC_CALL();
115 
116     SETPAR_AND_ADDCMD(MI_FORCE_WAKEUP, m_miItf, &cmdBuffer);
117 
118     return MOS_STATUS_SUCCESS;
119 }
120 
MHW_SETPAR_DECL_SRC(HUC_IMEM_STATE,AvcHucBrcInitPkt)121 MHW_SETPAR_DECL_SRC(HUC_IMEM_STATE, AvcHucBrcInitPkt)
122 {
123     auto setting = static_cast<AvcVdencFeatureSettings *>(m_featureManager->GetFeatureSettings()->GetConstSettings());
124     ENCODE_CHK_NULL_RETURN(setting);
125 
126     params.kernelDescriptor = setting->brcSettings.vdboxHucVdencBrcInitKernelDescriptor;
127 
128     return MOS_STATUS_SUCCESS;
129 }
130 
MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE,AvcHucBrcInitPkt)131 MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE, AvcHucBrcInitPkt)
132 {
133     ENCODE_CHK_STATUS_RETURN(SetDmemBuffer());
134 
135     params.function      = BRC_INIT;
136     params.hucDataSource = m_vdencBrcInitDmemBuffer[m_pipeline->m_currRecycledBufIdx];
137     params.dataLength    = MOS_ALIGN_CEIL(m_vdencBrcInitDmemBufferSize, CODECHAL_CACHELINE_SIZE);
138     params.dmemOffset    = HUC_DMEM_OFFSET_RTOS_GEMS;
139 
140     return MOS_STATUS_SUCCESS;
141 }
142 
MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE,AvcHucBrcInitPkt)143 MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE, AvcHucBrcInitPkt)
144 {
145     ENCODE_CHK_NULL_RETURN(m_basicFeature);
146     ENCODE_CHK_NULL_RETURN(m_basicFeature->m_recycleBuf);
147 
148     params.function = BRC_INIT;
149 
150     params.regionParams[0].presRegion = m_basicFeature->m_recycleBuf->GetBuffer(VdencBRCHistoryBuffer, m_basicFeature->m_frameNum);
151     params.regionParams[0].isWritable = true;
152 
153     return MOS_STATUS_SUCCESS;
154 }
155 
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)156 MOS_STATUS AvcHucBrcInitPkt::CalculateCommandSize(uint32_t &commandBufferSize, uint32_t &requestedPatchListSize)
157 {
158     ENCODE_FUNC_CALL();
159 
160     auto osInterface = m_hwInterface->GetOsInterface();
161     ENCODE_CHK_NULL_RETURN(osInterface);
162 
163     uint32_t hucCommandsSize = 0;
164     uint32_t hucPatchListSize = 0;
165     MHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams;
166 
167     ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucStateCommandSize(
168         m_basicFeature->m_mode, (uint32_t*)&hucCommandsSize, (uint32_t*)&hucPatchListSize, &stateCmdSizeParams));
169 
170     commandBufferSize = hucCommandsSize;
171     requestedPatchListSize = osInterface->bUsesPatchList ? hucPatchListSize : 0;
172 
173     // 4K align since allocation is in chunks of 4K bytes.
174     commandBufferSize = MOS_ALIGN_CEIL(commandBufferSize, CODECHAL_PAGE_SIZE);
175 
176     return MOS_STATUS_SUCCESS;
177 }
178 
SetDmemBuffer() const179 MOS_STATUS AvcHucBrcInitPkt::SetDmemBuffer()const
180 {
181     ENCODE_FUNC_CALL();
182 
183     // Setup BrcInit DMEM
184     auto hucVdencBrcInitDmem = (VdencAvcHucBrcInitDmem*)m_allocator->LockResourceForWrite(m_vdencBrcInitDmemBuffer[m_pipeline->m_currRecycledBufIdx]);
185     ENCODE_CHK_NULL_RETURN(hucVdencBrcInitDmem);
186     MOS_ZeroMemory(hucVdencBrcInitDmem, sizeof(VdencAvcHucBrcInitDmem));
187 
188     RUN_FEATURE_INTERFACE_RETURN(AvcEncodeBRC, AvcFeatureIDs::avcBrcFeature, SetDmemForInit, hucVdencBrcInitDmem);
189 
190     ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(m_vdencBrcInitDmemBuffer[m_pipeline->m_currRecycledBufIdx]));
191 
192     return MOS_STATUS_SUCCESS;
193 }
194 
195 #if USE_CODECHAL_DEBUG_TOOL
DumpHucBrcInit(bool isInput)196 MOS_STATUS AvcHucBrcInitPkt::DumpHucBrcInit(bool isInput)
197 {
198     ENCODE_FUNC_CALL();
199     int32_t currentPass = m_pipeline->GetCurrentPass();
200 
201     CodechalDebugInterface *debugInterface = m_pipeline->GetDebugInterface();
202     ENCODE_CHK_NULL_RETURN(debugInterface);
203 
204     auto settings = static_cast<AvcVdencFeatureSettings *>(m_featureManager->GetFeatureSettings()->GetConstSettings());
205     ENCODE_CHK_NULL_RETURN(settings);
206 
207     if (isInput)
208     {
209         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpHucDmem(m_vdencBrcInitDmemBuffer[m_pipeline->m_currRecycledBufIdx],
210             m_vdencBrcInitDmemBufferSize,
211             currentPass,
212             hucRegionDumpInit));
213     }
214 
215     auto vdencBRCHistoryBuffer = m_basicFeature->m_recycleBuf->GetBuffer(VdencBRCHistoryBuffer, 0);
216     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpHucRegion(
217         vdencBRCHistoryBuffer,
218         0,
219         settings->brcSettings.vdencBrcHistoryBufferSize,
220         0,
221         "_History",
222         isInput,
223         currentPass,
224         hucRegionDumpInit));
225 
226     return MOS_STATUS_SUCCESS;
227 }
228 
229 #endif
230 
231 }
232