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 //!
24 //! \file     encode_vp9_huc_brc_init_packet.cpp
25 //! \brief    Defines the interface for huc brc init/reset packet for VP9
26 //!
27 #include "encode_vp9_huc_brc_init_packet.h"
28 #include "encode_vp9_brc.h"
29 #include "encode_vp9_vdenc_feature_manager.h"
30 
31 namespace encode
32 {
33 
34 const uint32_t Vp9HucBrcInitPkt::m_brcInitDmem[48] =
35 {
36     0x00000000, 0x00038400, 0x00030D40, 0x000C3500, 0x00061A80, 0x00061A80, 0x00000000, 0x0000001E,
37     0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x270F0020, 0x02800000, 0x00010168,
38     0x000000FF, 0x0000000E, 0x00000073, 0x00000000, 0x00000000, 0x7846321E, 0x7846321E, 0x735A321E,
39     0xE5DFD8D1, 0x2F29211B, 0xE5DDD7D1, 0x5E56463F, 0xEAE3DAD4, 0x2F281F16, 0x01007488, 0x00000000,
40     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
41     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
42 };
43 
Init()44 MOS_STATUS Vp9HucBrcInitPkt::Init()
45 {
46     ENCODE_FUNC_CALL();
47     ENCODE_CHK_STATUS_RETURN(EncodeHucPkt::Init());
48     ENCODE_CHK_NULL_RETURN(m_featureManager);
49 
50     m_basicFeature = dynamic_cast<Vp9BasicFeature *>(m_featureManager->GetFeature(Vp9FeatureIDs::basicFeature));
51     ENCODE_CHK_NULL_RETURN(m_basicFeature);
52 
53     return MOS_STATUS_SUCCESS;
54 }
55 
Submit(MOS_COMMAND_BUFFER * commandBuffer,uint8_t packetPhase)56 MOS_STATUS Vp9HucBrcInitPkt::Submit(MOS_COMMAND_BUFFER *commandBuffer, uint8_t packetPhase)
57 {
58     ENCODE_FUNC_CALL();
59     ENCODE_CHK_NULL_RETURN(m_basicFeature);
60 
61     // To match watchdog timer threshold in codechal
62     ENCODE_CHK_STATUS_RETURN(m_miItf->SetWatchdogTimerThreshold(m_basicFeature->m_frameWidth, m_basicFeature->m_frameHeight, true));
63     bool firstTaskInPhase = packetPhase & firstPacket;
64     bool requestProlog    = false;
65 
66     if (!m_pipeline->IsSingleTaskPhaseSupported() || firstTaskInPhase)
67     {
68         // Send command buffer header at the beginning (OS dependent)
69         requestProlog = true;
70     }
71 
72     ENCODE_CHK_STATUS_RETURN(Execute(commandBuffer, true, requestProlog));
73 
74     RUN_FEATURE_INTERFACE_NO_RETURN(Vp9EncodeBrc, Vp9FeatureIDs::vp9BrcFeature, DisableBrcInitReset);
75 
76     CODECHAL_DEBUG_TOOL(
77         ENCODE_CHK_STATUS_RETURN(DumpInput());)
78 
79     return MOS_STATUS_SUCCESS;
80 }
81 
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)82 MOS_STATUS Vp9HucBrcInitPkt::CalculateCommandSize(uint32_t &commandBufferSize, uint32_t &requestedPatchListSize)
83 {
84     ENCODE_FUNC_CALL();
85 
86     auto osInterface = m_hwInterface->GetOsInterface();
87     ENCODE_CHK_NULL_RETURN(osInterface);
88 
89     MHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams;
90     uint32_t vdencHucStatesSize = 0;
91     uint32_t hucPatchListSize   = 0;
92 
93     ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucStateCommandSize(
94         m_basicFeature->m_mode, (uint32_t *)&vdencHucStatesSize, (uint32_t *)&hucPatchListSize, &stateCmdSizeParams));
95 
96     commandBufferSize      = vdencHucStatesSize;
97     requestedPatchListSize = osInterface->bUsesPatchList ? hucPatchListSize : 0;
98 
99     return MOS_STATUS_SUCCESS;
100 }
101 
DumpOutput()102 MOS_STATUS Vp9HucBrcInitPkt::DumpOutput()
103 {
104     ENCODE_FUNC_CALL();
105 
106 #if USE_CODECHAL_DEBUG_TOOL
107 
108     uint32_t brcHistoryBufferSize = 0;
109     RUN_FEATURE_INTERFACE_RETURN(Vp9EncodeBrc, Vp9FeatureIDs::vp9BrcFeature, GetBrcHistoryBufferSize, brcHistoryBufferSize);
110 
111     // Region 0: BRC History Buffer (In/Out)
112     ENCODE_CHK_STATUS_RETURN(DumpRegion(0, "_BrcHistoryBuffer", false, hucRegionDumpInit, brcHistoryBufferSize));
113 #endif
114 
115     return MOS_STATUS_SUCCESS;
116 }
117 
AllocateResources()118 MOS_STATUS Vp9HucBrcInitPkt::AllocateResources()
119 {
120     ENCODE_FUNC_CALL();
121     ENCODE_CHK_STATUS_RETURN(EncodeHucPkt::AllocateResources());
122 
123     // Initiate allocation parameters and lock flags
124     MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
125     MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
126     allocParamsForBufferLinear.Type     = MOS_GFXRES_BUFFER;
127     allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
128     allocParamsForBufferLinear.Format   = Format_Buffer;
129     allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE;
130 
131     // BRC init/reset DMEM
132     allocParamsForBufferLinear.dwBytes  = MOS_ALIGN_CEIL(sizeof(HucBrcInitDmem), CODECHAL_CACHELINE_SIZE);
133     allocParamsForBufferLinear.pBufName = "VDENC BrcInit DmemBuffer";
134     MOS_RESOURCE *allocatedBuffer       = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
135     ENCODE_CHK_NULL_RETURN(allocatedBuffer);
136     m_resVdencBrcInitDmemBuffer = *allocatedBuffer;
137 
138     return MOS_STATUS_SUCCESS;
139 }
140 
SetDmemBuffer() const141 MOS_STATUS Vp9HucBrcInitPkt::SetDmemBuffer() const
142 {
143     ENCODE_FUNC_CALL();
144 
145     // Setup BRC DMEM
146     HucBrcInitDmem *dmem = (HucBrcInitDmem *)m_allocator->LockResourceForWrite(const_cast<MOS_RESOURCE*>(&m_resVdencBrcInitDmemBuffer));
147     ENCODE_CHK_NULL_RETURN(dmem);
148 
149     MOS_SecureMemcpy(dmem, sizeof(HucBrcInitDmem), m_brcInitDmem, sizeof(m_brcInitDmem));
150 
151     RUN_FEATURE_INTERFACE_RETURN(Vp9EncodeBrc, Vp9FeatureIDs::vp9BrcFeature, SetDmemForInit, dmem);
152 
153     ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(const_cast<MOS_RESOURCE*>(&m_resVdencBrcInitDmemBuffer)));
154 
155     return MOS_STATUS_SUCCESS;
156 }
157 
158 #if USE_CODECHAL_DEBUG_TOOL
DumpInput()159 MOS_STATUS Vp9HucBrcInitPkt::DumpInput()
160 {
161     ENCODE_FUNC_CALL();
162 
163     // Dump Huc/Brc init
164     CodechalDebugInterface *debugInterface = m_pipeline->GetDebugInterface();
165     ENCODE_CHK_NULL_RETURN(debugInterface);
166 
167     ENCODE_CHK_STATUS_RETURN(debugInterface->DumpHucDmem(
168         &m_resVdencBrcInitDmemBuffer,
169         sizeof(HucBrcInitDmem),
170         0,
171         hucRegionDumpInit));
172 
173     uint32_t brcHistoryBufferSize = 0;
174     RUN_FEATURE_INTERFACE_RETURN(Vp9EncodeBrc, Vp9FeatureIDs::vp9BrcFeature, GetBrcHistoryBufferSize, brcHistoryBufferSize);
175 
176     // Region 0: BRC History Buffer (In/Out)
177     ENCODE_CHK_STATUS_RETURN(DumpRegion(0, "_BrcHistoryBuffer", true, hucRegionDumpInit, brcHistoryBufferSize));
178 
179     return MOS_STATUS_SUCCESS;
180 }
181 #endif
182 
MHW_SETPAR_DECL_SRC(HUC_IMEM_STATE,Vp9HucBrcInitPkt)183 MHW_SETPAR_DECL_SRC(HUC_IMEM_STATE, Vp9HucBrcInitPkt)
184 {
185     ENCODE_FUNC_CALL();
186 
187     params.kernelDescriptor = m_vdboxHucVp9VdencBrcInitKernelDescriptor;
188 
189     return MOS_STATUS_SUCCESS;
190 }
191 
MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE,Vp9HucBrcInitPkt)192 MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE, Vp9HucBrcInitPkt)
193 {
194     ENCODE_FUNC_CALL();
195 
196     ENCODE_CHK_STATUS_RETURN(SetDmemBuffer());
197 
198     params.function      = BRC_INIT;
199     params.hucDataSource = const_cast<PMOS_RESOURCE>(&m_resVdencBrcInitDmemBuffer);
200     params.dataLength    = MOS_ALIGN_CEIL(sizeof(HucBrcInitDmem), CODECHAL_CACHELINE_SIZE);
201     params.dmemOffset    = HUC_DMEM_OFFSET_RTOS_GEMS;
202 
203     return MOS_STATUS_SUCCESS;
204 }
205 
MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE,Vp9HucBrcInitPkt)206 MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE, Vp9HucBrcInitPkt)
207 {
208     ENCODE_FUNC_CALL();
209 
210     ENCODE_CHK_NULL_RETURN(m_basicFeature);
211     ENCODE_CHK_NULL_RETURN(m_basicFeature->m_recycleBuf);
212 
213     // Set regions virtual address parameters
214     params.regionParams[0].presRegion = m_basicFeature->m_recycleBuf->GetBuffer(VdencBRCHistoryBuffer, m_basicFeature->m_frameNum);
215     params.regionParams[0].isWritable = true;
216 
217     return MOS_STATUS_SUCCESS;
218 }
219 
220 }  // namespace encode
221