1 /*
2 * Copyright (c) 2017-2020, 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     codechal_encode_sw_scoreboard.cpp
24 //! \brief    Defines base class for SW scoreboard init kernel
25 //!
26 
27 #include "codechal_encoder_base.h"
28 #include "codechal_encode_sw_scoreboard.h"
29 #include "codeckrnheader.h"
30 #include "hal_oca_interface.h"
31 
AllocateResources()32 MOS_STATUS CodechalEncodeSwScoreboard::AllocateResources()
33 {
34     CODECHAL_ENCODE_FUNCTION_ENTER;
35 
36     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
37 
38     if (Mos_ResourceIsNull(&m_surfaceParams.swScoreboardSurface[m_surfaceParams.surfaceIndex].OsResource))
39     {
40         MOS_ZeroMemory(&m_surfaceParams.swScoreboardSurface[m_surfaceParams.surfaceIndex], sizeof(MOS_SURFACE));
41 
42         MOS_ALLOC_GFXRES_PARAMS  allocParamsForBuffer2D;
43         MOS_ZeroMemory(&allocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS));
44         allocParamsForBuffer2D.Type     = MOS_GFXRES_2D;
45         allocParamsForBuffer2D.TileType = MOS_TILE_LINEAR;
46         allocParamsForBuffer2D.Format   = Format_R32U;
47         allocParamsForBuffer2D.dwWidth  = m_surfaceParams.swScoreboardSurfaceWidth;
48         allocParamsForBuffer2D.dwHeight = m_surfaceParams.swScoreboardSurfaceHeight;
49         allocParamsForBuffer2D.pBufName = "SW scoreboard init Buffer";
50 
51         MEDIA_WA_TABLE* waTable = m_osInterface->pfnGetWaTable(m_osInterface);
52         if (MEDIA_IS_WA(waTable, WaForceAllocateLML4))
53         {
54             // If L4-PCIe WA is enabled, allocate in device memory
55             // And do not let CPU write to device memory later below
56             allocParamsForBuffer2D.dwMemType = MOS_MEMPOOL_DEVICEMEMORY;
57         }
58 
59         CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
60             m_osInterface,
61             &allocParamsForBuffer2D,
62             &m_surfaceParams.swScoreboardSurface[m_surfaceParams.surfaceIndex].OsResource),
63             "Failed to allocate SW scoreboard init Buffer.");
64 
65         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface,
66             &m_surfaceParams.swScoreboardSurface[m_surfaceParams.surfaceIndex]));
67 
68         if (!MEDIA_IS_WA(waTable, WaForceAllocateLML4))
69         {
70             MOS_LOCK_PARAMS lockFlagsWriteOnly;
71             MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
72             lockFlagsWriteOnly.WriteOnly = 1;
73 
74             uint8_t* pData = (uint8_t*)m_osInterface->pfnLockResource(
75                 m_osInterface,
76                 &m_surfaceParams.swScoreboardSurface[m_surfaceParams.surfaceIndex].OsResource,
77                 &lockFlagsWriteOnly);
78 
79             if (pData == nullptr)
80             {
81                 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock SW scoreboard init Buffer");
82                 eStatus = MOS_STATUS_UNKNOWN;
83                 return eStatus;
84             }
85 
86             uint32_t size =
87                 m_surfaceParams.swScoreboardSurface[m_surfaceParams.surfaceIndex].dwPitch *
88                 m_surfaceParams.swScoreboardSurface[m_surfaceParams.surfaceIndex].dwHeight;
89             MOS_ZeroMemory(pData, size);
90 
91             m_osInterface->pfnUnlockResource(
92                 m_osInterface, &m_surfaceParams.swScoreboardSurface[m_surfaceParams.surfaceIndex].OsResource);
93         }
94     }
95 
96     return eStatus;
97 }
98 
ReleaseResources()99 void CodechalEncodeSwScoreboard::ReleaseResources()
100 {
101     for (auto i = 0; i < CODECHAL_ENCODE_SW_SCOREBOARD_SURFACE_NUM; i++)
102     {
103         if (!Mos_ResourceIsNull(&m_surfaceParams.swScoreboardSurface[i].OsResource))
104         {
105             m_osInterface->pfnFreeResource(
106                 m_osInterface,
107                 &m_surfaceParams.swScoreboardSurface[i].OsResource);
108         }
109     }
110 }
111 
GetBTCount()112 uint8_t CodechalEncodeSwScoreboard::GetBTCount()
113 {
114     return (uint8_t)swScoreboardNumSurfaces;
115 }
116 
SetCurbe()117 MOS_STATUS CodechalEncodeSwScoreboard::SetCurbe()
118 {
119     CODECHAL_ENCODE_FUNCTION_ENTER;
120 
121     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
122     CurbeData                   curbe;
123 
124     MOS_ZeroMemory(&curbe, sizeof(CurbeData));
125 
126     // ScoreboardWidth and Height in units of Thread Space
127     curbe.DW0.scoreboardWidth          = m_curbeParams.scoreboardWidth;
128     curbe.DW0.scoreboardHeight         = m_curbeParams.scoreboardHeight;
129     curbe.DW1.isHevc                   = m_curbeParams.isHevc;
130     curbe.DW2.numberOfWaveFrontsSplits = m_curbeParams.numberOfWaveFrontSplit;
131     curbe.DW2.numberofChildThreads     = m_curbeParams.numberOfChildThread;
132     curbe.DW4.dependencyPattern        = m_dependencyPatternIdx;
133     curbe.DW16.softwareScoreboard      = swScoreboardInitSurface;
134     curbe.DW17.lcuInfoSurface          = swScoreboardInitLcuInfoSurface;
135 
136     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_kernelState->m_dshRegion.AddData(
137         &curbe,
138         m_kernelState->dwCurbeOffset,
139         sizeof(curbe)));
140 
141     return eStatus;
142 }
143 
SendSurface(PMOS_COMMAND_BUFFER cmdBuffer)144 MOS_STATUS CodechalEncodeSwScoreboard::SendSurface(PMOS_COMMAND_BUFFER cmdBuffer)
145 {
146     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
147 
148     CODECHAL_ENCODE_FUNCTION_ENTER;
149 
150     CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
151 
152     // Set Surface States
153     CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams;
154     MOS_ZeroMemory(&surfaceCodecParams, sizeof(surfaceCodecParams));
155     surfaceCodecParams.bIs2DSurface            = true;
156     surfaceCodecParams.bMediaBlockRW           = true;
157     surfaceCodecParams.bIsWritable             = true;
158     surfaceCodecParams.bRenderTarget           = true;
159     surfaceCodecParams.psSurface               = &m_surfaceParams.swScoreboardSurface[m_surfaceParams.surfaceIndex];
160     surfaceCodecParams.dwCacheabilityControl   = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_SOFTWARE_SCOREBOARD_ENCODE].Value;
161     surfaceCodecParams.dwBindingTableOffset    = swScoreboardInitSurface;
162     surfaceCodecParams.bUse32UINTSurfaceFormat = true;
163 
164     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
165         m_hwInterface,
166         cmdBuffer,
167         &surfaceCodecParams,
168         m_kernelState));
169 
170     if (m_surfaceParams.lcuInfoSurface)
171     {
172         MOS_ZeroMemory(&surfaceCodecParams, sizeof(surfaceCodecParams));
173         surfaceCodecParams.bIs2DSurface            = true;
174         surfaceCodecParams.bMediaBlockRW           = true;
175         surfaceCodecParams.bIsWritable             = true;
176         surfaceCodecParams.bRenderTarget           = true;
177         surfaceCodecParams.psSurface               = m_surfaceParams.lcuInfoSurface;
178         surfaceCodecParams.dwBindingTableOffset    = swScoreboardInitLcuInfoSurface;
179         surfaceCodecParams.bUse32UINTSurfaceFormat = true;
180 
181         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
182             m_hwInterface,
183             cmdBuffer,
184             &surfaceCodecParams,
185             m_kernelState));
186     }
187 
188     return eStatus;
189 }
190 
Execute(KernelParams * params)191 MOS_STATUS CodechalEncodeSwScoreboard::Execute(KernelParams *params)
192 {
193     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
194 
195     CODECHAL_ENCODE_FUNCTION_ENTER;
196 
197     CODECHAL_ENCODE_CHK_NULL_RETURN(params);
198 
199     PerfTagSetting perfTag;
200     CODECHAL_ENCODE_SET_PERFTAG_INFO(perfTag, CODECHAL_ENCODE_PERFTAG_CALL_SCOREBOARD);
201 
202     // Allocate output surface
203     m_surfaceParams.isHevc                    = params->isHevc;
204     m_surfaceParams.swScoreboardSurfaceWidth  = params->swScoreboardSurfaceWidth;
205     m_surfaceParams.swScoreboardSurfaceHeight = params->swScoreboardSurfaceHeight;
206     if (m_surfaceParams.isHevc)
207     {
208         m_surfaceParams.lcuInfoSurface         = params->lcuInfoSurface;
209     }
210 
211     CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateResources());
212 
213     // If Single Task Phase is not enabled, use BT count for the kernel state.
214     if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported)
215     {
216         auto maxBtCount = m_singleTaskPhaseSupported ?
217             m_maxBtCount : m_kernelState->KernelParams.iBTCount;
218         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->RequestSshSpaceForCmdBuf(maxBtCount));
219         m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(maxBtCount);
220         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->VerifySpaceAvailable());
221     }
222 
223     // setup DSH and Interface Descriptor
224     auto stateHeapInterface = m_renderInterface->m_stateHeapInterface;
225     CODECHAL_ENCODE_CHK_NULL_RETURN(stateHeapInterface);
226     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
227         stateHeapInterface,
228         m_kernelState,
229         false,
230         0,
231         false,
232         m_storeData));
233 
234     MHW_INTERFACE_DESCRIPTOR_PARAMS idParams;
235     MOS_ZeroMemory(&idParams, sizeof(idParams));
236     idParams.pKernelState = m_kernelState;
237     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->SetInterfaceDescriptor(1, &idParams));
238 
239     // Setup Curbe
240     m_curbeParams.scoreboardWidth        = params->scoreboardWidth;
241     m_curbeParams.scoreboardHeight       = params->scoreboardHeight;
242     m_curbeParams.isHevc                 = params->isHevc;
243     m_curbeParams.numberOfWaveFrontSplit = params->numberOfWaveFrontSplit;
244     m_curbeParams.numberOfChildThread    = params->numberOfChildThread;
245 
246     CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbe());
247 
248     CODECHAL_MEDIA_STATE_TYPE encFunctionType = CODECHAL_MEDIA_STATE_SW_SCOREBOARD_INIT;
249     CODECHAL_DEBUG_TOOL(
250         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
251             encFunctionType,
252             MHW_DSH_TYPE,
253             m_kernelState));
254         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
255             encFunctionType,
256             m_kernelState));
257         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
258             encFunctionType,
259             MHW_ISH_TYPE,
260             m_kernelState));
261     )
262 
263     MOS_COMMAND_BUFFER cmdBuffer;
264     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
265 
266     SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams();
267     sendKernelCmdsParams.EncFunctionType = encFunctionType;
268     sendKernelCmdsParams.pKernelState = m_kernelState;
269     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams));
270 
271     // add binding table
272     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->SetBindingTable(m_kernelState));
273 
274     // send surfaces
275     CODECHAL_ENCODE_CHK_STATUS_RETURN(SendSurface(&cmdBuffer));
276 
277     CODECHAL_DEBUG_TOOL(
278         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
279             encFunctionType,
280             MHW_SSH_TYPE,
281             m_kernelState));
282     )
283 
284     // Thread Dispatch Pattern - MEDIA OBJECT WALKER
285     CODECHAL_WALKER_CODEC_PARAMS walkerCodecParams;
286     MOS_ZeroMemory(&walkerCodecParams, sizeof(walkerCodecParams));
287     walkerCodecParams.WalkerMode              = m_walkerMode;
288     walkerCodecParams.dwResolutionX           = (uint32_t)(ceil)((m_curbeParams.scoreboardWidth) / 4.0);
289     walkerCodecParams.dwResolutionY           = (uint32_t)(ceil)((m_curbeParams.scoreboardHeight) / 4.0);
290     walkerCodecParams.bNoDependency           = true;
291     walkerCodecParams.bGroupIdSelectSupported = m_groupIdSelectSupported;
292 
293     MHW_WALKER_PARAMS walkerParams;
294     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalInitMediaObjectWalkerParams(m_hwInterface, &walkerParams, &walkerCodecParams));
295 
296     HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, __FUNCTION__, sizeof(__FUNCTION__));
297     HalOcaInterface::OnDispatch(cmdBuffer, *m_osInterface, *m_miInterface, *m_renderInterface->GetMmioRegisters());
298 
299     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderInterface->AddMediaObjectWalkerCmd(&cmdBuffer, &walkerParams));
300 
301     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->EndStatusReport(&cmdBuffer, encFunctionType));
302 
303     CODECHAL_DEBUG_TOOL(
304         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
305             encFunctionType,
306             MHW_SSH_TYPE,
307             m_kernelState));
308 
309         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
310             &cmdBuffer,
311             encFunctionType,
312             nullptr));
313     )
314 
315     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->SubmitBlocks(m_kernelState));
316     if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
317     {
318         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->UpdateGlobalCmdBufId());
319         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
320     }
321 
322     CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
323             &cmdBuffer,
324             encFunctionType,
325             nullptr)));
326 
327     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(
328         &cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase));
329 
330     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
331 
332     if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
333     {
334         HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
335         m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw);
336         m_lastTaskInPhase = false;
337     }
338 
339     return eStatus;
340 }
341 
CodechalEncodeSwScoreboard(CodechalEncoderState * encoder)342 CodechalEncodeSwScoreboard::CodechalEncodeSwScoreboard(CodechalEncoderState *encoder)
343     : m_useHwScoreboard(encoder->m_useHwScoreboard),
344     m_renderContextUsesNullHw(encoder->m_renderContextUsesNullHw),
345     m_groupIdSelectSupported(encoder->m_groupIdSelectSupported),
346     m_singleTaskPhaseSupported(encoder->m_singleTaskPhaseSupported),
347     m_firstTaskInPhase(encoder->m_firstTaskInPhase),
348     m_lastTaskInPhase(encoder->m_lastTaskInPhase),
349     m_groupId(encoder->m_groupId),
350     m_pictureCodingType(encoder->m_pictureCodingType),
351     m_mode(encoder->m_mode),
352     m_verticalLineStride(encoder->m_verticalLineStride),
353     m_maxBtCount(encoder->m_maxBtCount),
354     m_vmeStatesSize(encoder->m_vmeStatesSize),
355     m_storeData(encoder->m_storeData),
356     m_walkerMode(encoder->m_walkerMode)
357 {
358     CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(encoder);
359 
360     // Initilize interface pointers
361     m_encoder               = encoder;
362     m_osInterface           = encoder->GetOsInterface();
363     m_hwInterface           = encoder->GetHwInterface();
364     m_debugInterface        = encoder->GetDebugInterface();
365     m_miInterface           = m_hwInterface->GetMiInterface();
366     m_renderInterface       = m_hwInterface->GetRenderInterface();
367     m_stateHeapInterface    = m_renderInterface->m_stateHeapInterface->pStateHeapInterface;
368     m_curbeLength           = sizeof(CurbeData);
369     m_kernelBase            = encoder->m_kernelBase;
370     m_kuidCommon            = IDR_CODEC_HME_DS_SCOREBOARD_KERNEL;
371 }
372 
~CodechalEncodeSwScoreboard()373 CodechalEncodeSwScoreboard::~CodechalEncodeSwScoreboard()
374 {
375     // free SW scoreboard init surface
376     ReleaseResources();
377 
378     if (m_kernelState)
379     {
380         MOS_Delete(m_kernelState);
381         m_kernelState = nullptr;
382     }
383 }
384