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