1 /*
2 * Copyright (c) 2022, 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 media_vebox_copy_next.cpp
24 //! \brief Common Copy interface and structure used in Vebox Engine
25 //! \details Common Copy interface and structure used in Vebox Engine
26 #include "media_vebox_copy_next.h"
27 #include "renderhal.h"
28 #include "mhw_vebox_itf.h"
29 #include "mos_os_cp_interface_specific.h"
30 #include "media_copy_common.h"
31 #include "hal_oca_interface_next.h"
32
33 #define SURFACE_DW_UY_OFFSET(pSurface) \
34 ((pSurface) != nullptr ? ((pSurface)->UPlaneOffset.iSurfaceOffset - (pSurface)->dwOffset) / (pSurface)->dwPitch + (pSurface)->UPlaneOffset.iYOffset : 0)
35
36 #define SURFACE_DW_VY_OFFSET(pSurface) \
37 ((pSurface) != nullptr ? ((pSurface)->VPlaneOffset.iSurfaceOffset - (pSurface)->dwOffset) / (pSurface)->dwPitch + (pSurface)->VPlaneOffset.iYOffset : 0)
38
VeboxCopyStateNext(PMOS_INTERFACE osInterface)39 VeboxCopyStateNext::VeboxCopyStateNext(PMOS_INTERFACE osInterface) :
40 m_osInterface(osInterface),
41 m_mhwInterfaces(nullptr),
42 m_cpInterface(nullptr)
43 {
44 MOS_ZeroMemory(¶ms, sizeof(params));
45 params.Flags.m_vebox = 1;
46 m_mhwInterfaces = MhwInterfacesNext::CreateFactory(params, osInterface);
47 if (m_mhwInterfaces != nullptr)
48 {
49 m_miItf = m_mhwInterfaces->m_miItf;
50 m_veboxItf = m_mhwInterfaces->m_veboxItf;
51 }
52 }
53
VeboxCopyStateNext(PMOS_INTERFACE osInterface,MhwInterfacesNext * mhwInterfaces)54 VeboxCopyStateNext::VeboxCopyStateNext(PMOS_INTERFACE osInterface, MhwInterfacesNext* mhwInterfaces) :
55 m_osInterface(osInterface),
56 m_mhwInterfaces(nullptr),
57 m_cpInterface(nullptr)
58 {
59 m_cpInterface = mhwInterfaces->m_cpInterface;
60 m_miItf = mhwInterfaces->m_miItf;
61 m_veboxItf = mhwInterfaces->m_veboxItf;
62 }
63
~VeboxCopyStateNext()64 VeboxCopyStateNext::~VeboxCopyStateNext()
65 {
66 if (m_veboxItf != nullptr)
67 {
68 m_veboxItf->DestroyHeap();
69 }
70
71 if(m_mhwInterfaces != nullptr)
72 {
73 m_mhwInterfaces->Destroy();
74 MOS_Delete(m_mhwInterfaces);
75 }
76 }
77
Initialize()78 MOS_STATUS VeboxCopyStateNext::Initialize()
79 {
80 VEBOX_COPY_CHK_NULL_RETURN(m_veboxItf);
81 const MHW_VEBOX_HEAP* veboxHeap = nullptr;
82 m_veboxItf->GetVeboxHeapInfo(&veboxHeap);
83
84 if (veboxHeap == nullptr)
85 {
86 m_veboxItf->CreateHeap();
87 }
88
89 return MOS_STATUS_SUCCESS;
90 }
91
CopyMainSurface(PMOS_SURFACE src,PMOS_SURFACE dst)92 MOS_STATUS VeboxCopyStateNext::CopyMainSurface(PMOS_SURFACE src, PMOS_SURFACE dst)
93 {
94 VEBOX_COPY_CHK_NULL_RETURN(src);
95 VEBOX_COPY_CHK_NULL_RETURN(dst);
96 return CopyMainSurface(&src->OsResource, &dst->OsResource);
97 }
98
CopyMainSurface(PMOS_RESOURCE src,PMOS_RESOURCE dst)99 MOS_STATUS VeboxCopyStateNext::CopyMainSurface(PMOS_RESOURCE src, PMOS_RESOURCE dst)
100 {
101 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
102 MHW_VEBOX_STATE_CMD_PARAMS veboxStateCmdParams;
103 MOS_COMMAND_BUFFER cmdBuffer;
104 MHW_VEBOX_SURFACE_STATE_CMD_PARAMS mhwVeboxSurfaceStateCmdParams;
105 uint32_t streamID = 0;
106 const MHW_VEBOX_HEAP *veboxHeap = nullptr;
107 MOS_SURFACE inputSurface, outputSurface;
108
109 VEBOX_COPY_CHK_NULL_RETURN(src);
110 VEBOX_COPY_CHK_NULL_RETURN(dst);
111 VEBOX_COPY_CHK_NULL_RETURN(m_miItf);
112 VEBOX_COPY_CHK_NULL_RETURN(m_veboxItf);
113
114 // Get input resource info
115 MOS_ZeroMemory(&inputSurface, sizeof(MOS_SURFACE));
116 inputSurface.OsResource = *src;
117 GetResourceInfo(&inputSurface);
118
119 // Get output resource info
120 MOS_ZeroMemory(&outputSurface, sizeof(MOS_SURFACE));
121 outputSurface.OsResource = *dst;
122 GetResourceInfo(&outputSurface);
123
124 // For RGB10/BGR10/Y210/Y410/A8, use other format instead. No need to check format again.
125 AdjustSurfaceFormat(inputSurface);
126
127 MHW_VEBOX_GPUNODE_LIMIT GpuNodeLimit;
128 MOS_GPU_NODE VeboxGpuNode;
129 MOS_GPU_CONTEXT VeboxGpuContext;
130 GpuNodeLimit.bCpEnabled = (m_osInterface->osCpInterface->IsCpEnabled()) ? true : false;
131 VEBOX_COPY_CHK_STATUS_RETURN(m_veboxItf->FindVeboxGpuNodeToUse(&GpuNodeLimit));
132 VeboxGpuNode = (MOS_GPU_NODE)(GpuNodeLimit.dwGpuNodeToUse);
133 VeboxGpuContext = (VeboxGpuNode == MOS_GPU_NODE_VE) ? MOS_GPU_CONTEXT_VEBOX : MOS_GPU_CONTEXT_VEBOX2;
134 // Create VEBOX/VEBOX2 Context
135 VEBOX_COPY_CHK_STATUS_RETURN(CreateGpuContext(
136 m_osInterface,
137 VeboxGpuContext,
138 VeboxGpuNode));
139
140 // Register Vebox GPU context with the Batch Buffer completion event
141 VEBOX_COPY_CHK_STATUS_RETURN(m_osInterface->pfnRegisterBBCompleteNotifyEvent(
142 m_osInterface,
143 VeboxGpuContext));
144
145 VEBOX_COPY_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(m_osInterface, VeboxGpuContext));
146
147 m_osInterface->pfnSetPerfTag(m_osInterface, VEBOX_COPY);
148
149 // Reset allocation list and house keeping
150 m_osInterface->pfnResetOsStates(m_osInterface);
151
152 VEBOX_COPY_CHK_STATUS_RETURN(m_veboxItf->GetVeboxHeapInfo(&veboxHeap));
153 VEBOX_COPY_CHK_NULL_RETURN(m_osInterface->osCpInterface);
154
155 //there is a new usage that input surface is clear and output surface is secure.
156 //replace Huc Copy by DoubleBuffer resolve to update ccs data.
157 //So need consolidate both input/output surface information to decide cp context.
158 PMOS_RESOURCE surfaceArray[2];
159 surfaceArray[0] = src;
160 surfaceArray[1] = dst;
161
162 // preprocess in cp first
163 VEBOX_COPY_CHK_STATUS_RETURN(
164 m_osInterface->osCpInterface->PrepareResources((void **)&surfaceArray, sizeof(surfaceArray) / sizeof(PMOS_RESOURCE), nullptr, 0));
165
166 // initialize the command buffer struct
167 MOS_ZeroMemory(&cmdBuffer, sizeof(MOS_COMMAND_BUFFER));
168
169 VEBOX_COPY_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
170 VEBOX_COPY_CHK_STATUS_RETURN(InitCommandBuffer(&cmdBuffer));
171
172 HalOcaInterfaceNext::On1stLevelBBStart(cmdBuffer, m_osInterface->pOsContext, m_osInterface->CurrentGpuContextHandle, m_miItf, *m_miItf->GetMmioRegisters());
173
174 MediaPerfProfiler* perfProfiler = MediaPerfProfiler::Instance();
175 VEBOX_COPY_CHK_NULL_RETURN(perfProfiler);
176 VEBOX_COPY_CHK_STATUS_RETURN(perfProfiler->AddPerfCollectStartCmd((void*)this, m_osInterface, m_miItf, &cmdBuffer));
177 VEBOX_COPY_CHK_STATUS_RETURN(NullHW::StartPredicateNext(m_osInterface, m_miItf, &cmdBuffer));
178 // Set Vebox MMIO
179 VEBOX_COPY_CHK_STATUS_RETURN(m_miItf->AddVeboxMMIOPrologCmd(&cmdBuffer));
180
181 // Prepare Vebox_Surface_State, surface input/and output are the same but the compressed status.
182 VEBOX_COPY_CHK_STATUS_RETURN(SetupVeboxSurfaceState(&mhwVeboxSurfaceStateCmdParams, &inputSurface, &outputSurface));
183
184 //---------------------------------
185 // Send CMD: Vebox_Surface_State
186 //---------------------------------
187 VEBOX_COPY_CHK_STATUS_RETURN(m_veboxItf->AddVeboxSurfaces(
188 &cmdBuffer,
189 &mhwVeboxSurfaceStateCmdParams));
190
191 HalOcaInterfaceNext::OnDispatch(cmdBuffer, *m_osInterface, m_miItf, *m_miItf->GetMmioRegisters());
192
193 //---------------------------------
194 // Send CMD: Vebox_Tiling_Convert
195 //---------------------------------
196 VEBOX_COPY_CHK_STATUS_RETURN(m_veboxItf->AddVeboxTilingConvert(&cmdBuffer, &mhwVeboxSurfaceStateCmdParams.SurfInput, &mhwVeboxSurfaceStateCmdParams.SurfOutput));
197
198 auto& flushDwParams = m_miItf->MHW_GETPAR_F(MI_FLUSH_DW)();
199 flushDwParams = {};
200 VEBOX_COPY_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(&cmdBuffer));
201
202 if (!m_osInterface->bEnableKmdMediaFrameTracking && veboxHeap)
203 {
204 flushDwParams = {};
205 flushDwParams.pOsResource = (PMOS_RESOURCE)&veboxHeap->DriverResource;
206 flushDwParams.dwResourceOffset = veboxHeap->uiOffsetSync;
207 flushDwParams.dwDataDW1 = veboxHeap->dwNextTag;
208
209 auto skuTable = m_osInterface->pfnGetSkuTable(m_osInterface);
210 if (skuTable && MEDIA_IS_SKU(skuTable, FtrEnablePPCFlush))
211 {
212 flushDwParams.bEnablePPCFlush = true;
213 }
214 VEBOX_COPY_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(&cmdBuffer));
215 }
216 VEBOX_COPY_CHK_STATUS_RETURN(NullHW::StopPredicateNext(m_osInterface, m_miItf, &cmdBuffer));
217 VEBOX_COPY_CHK_STATUS_RETURN(perfProfiler->AddPerfCollectEndCmd((void*)this, m_osInterface, m_miItf, &cmdBuffer));
218
219 HalOcaInterfaceNext::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
220
221 VEBOX_COPY_CHK_STATUS_RETURN(m_miItf->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
222
223 // Return unused command buffer space to OS
224 m_osInterface->pfnReturnCommandBuffer(
225 m_osInterface,
226 &cmdBuffer,
227 0);
228
229 // Flush the command buffer
230 VEBOX_COPY_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
231 m_osInterface,
232 &cmdBuffer,
233 false));
234
235 m_veboxItf->UpdateVeboxSync();
236
237 return eStatus;
238 }
239
IsSurfaceSupported(PMOS_RESOURCE surface)240 bool VeboxCopyStateNext::IsSurfaceSupported(PMOS_RESOURCE surface)
241 {
242 bool supported = false;
243 MOS_SURFACE inputSurface;
244
245 if (!surface)
246 {
247 return false;
248 }
249
250 // Get input resource info
251 MOS_ZeroMemory(&inputSurface, sizeof(MOS_SURFACE));
252 inputSurface.OsResource = *surface;
253 GetResourceInfo(&inputSurface);
254
255 supported = IsVeCopySupportedFormat(inputSurface.Format);
256
257 if (inputSurface.TileType == MOS_TILE_LINEAR &&
258 (inputSurface.dwPitch % 64))
259 {
260 supported = false;
261 }
262
263 return supported;
264 }
265
GetResourceInfo(PMOS_SURFACE surface)266 MOS_STATUS VeboxCopyStateNext::GetResourceInfo(PMOS_SURFACE surface)
267 {
268 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
269
270 VEBOX_COPY_CHK_NULL_RETURN(m_osInterface);
271 VEBOX_COPY_CHK_NULL_RETURN(surface);
272
273 MOS_SURFACE resDetails;
274 MOS_ZeroMemory(&resDetails, sizeof(resDetails));
275 resDetails.Format = Format_Invalid;
276
277 VEBOX_COPY_CHK_STATUS_RETURN(m_osInterface->pfnGetResourceInfo(
278 m_osInterface,
279 &surface->OsResource,
280 &resDetails));
281
282 surface->Format = resDetails.Format;
283 surface->dwWidth = resDetails.dwWidth;
284 surface->dwHeight = resDetails.dwHeight;
285 surface->dwPitch = resDetails.dwPitch;
286 surface->dwDepth = resDetails.dwDepth;
287 surface->bArraySpacing = resDetails.bArraySpacing;
288 surface->TileType = resDetails.TileType;
289 surface->TileModeGMM = resDetails.TileModeGMM;
290 surface->bGMMTileEnabled = resDetails.bGMMTileEnabled;
291 surface->bCompressible = resDetails.bCompressible;
292 surface->bIsCompressed = resDetails.bIsCompressed;
293 surface->dwOffset = resDetails.RenderOffset.YUV.Y.BaseOffset + surface->OsResource.dwOffsetForMono;
294 surface->YPlaneOffset.iSurfaceOffset = resDetails.RenderOffset.YUV.Y.BaseOffset;
295 surface->YPlaneOffset.iXOffset = resDetails.RenderOffset.YUV.Y.XOffset;
296 surface->YPlaneOffset.iYOffset = resDetails.RenderOffset.YUV.Y.YOffset;
297 surface->UPlaneOffset.iSurfaceOffset = resDetails.RenderOffset.YUV.U.BaseOffset;
298 surface->UPlaneOffset.iXOffset = resDetails.RenderOffset.YUV.U.XOffset;
299 surface->UPlaneOffset.iYOffset = resDetails.RenderOffset.YUV.U.YOffset;
300 surface->VPlaneOffset.iSurfaceOffset = resDetails.RenderOffset.YUV.V.BaseOffset;
301 surface->VPlaneOffset.iXOffset = resDetails.RenderOffset.YUV.V.XOffset;
302 surface->VPlaneOffset.iYOffset = resDetails.RenderOffset.YUV.V.YOffset;
303 surface->dwSize = (uint32_t)surface->OsResource.pGmmResInfo->GetSizeMainSurface();
304
305 MOS_MEMCOMP_STATE mmcMode;
306
307 MOS_ZeroMemory(&mmcMode, sizeof(mmcMode));
308 m_osInterface->pfnGetMemoryCompressionMode(m_osInterface, &surface->OsResource, &mmcMode);
309 surface->CompressionMode = (MOS_RESOURCE_MMC_MODE)mmcMode;
310
311 if (mmcMode)
312 {
313 m_osInterface->pfnGetMemoryCompressionFormat(m_osInterface, &surface->OsResource, &surface->CompressionFormat);
314 if ((surface->TileType == MOS_TILE_Y ||
315 surface->TileType == MOS_TILE_YS))
316 {
317 surface->bCompressible = true;
318 surface->bIsCompressed = true;
319 surface->CompressionMode = (MOS_RESOURCE_MMC_MODE)mmcMode;
320 }
321 }
322
323 return eStatus;
324 }
325
SetupVeboxSurfaceState(PMHW_VEBOX_SURFACE_STATE_CMD_PARAMS mhwVeboxSurfaceStateCmdParams,PMOS_SURFACE inputSurface,PMOS_SURFACE outputSurface)326 MOS_STATUS VeboxCopyStateNext::SetupVeboxSurfaceState(
327 PMHW_VEBOX_SURFACE_STATE_CMD_PARAMS mhwVeboxSurfaceStateCmdParams,
328 PMOS_SURFACE inputSurface,
329 PMOS_SURFACE outputSurface)
330 {
331 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
332 bool inputIsLinearBuffer = false;
333 bool outputIsLinearBuffer = false;
334 uint32_t bpp = 1;
335 uint32_t inputWidth = 0;
336 uint32_t outputWidth = 0;
337
338 VEBOX_COPY_CHK_NULL_RETURN(inputSurface);
339 VEBOX_COPY_CHK_NULL_RETURN(mhwVeboxSurfaceStateCmdParams);
340
341 MOS_ZeroMemory(mhwVeboxSurfaceStateCmdParams, sizeof(*mhwVeboxSurfaceStateCmdParams));
342
343 mhwVeboxSurfaceStateCmdParams->SurfInput.bActive = mhwVeboxSurfaceStateCmdParams->SurfOutput.bActive = true;
344 mhwVeboxSurfaceStateCmdParams->SurfInput.dwBitDepth = mhwVeboxSurfaceStateCmdParams->SurfOutput.dwBitDepth = inputSurface->dwDepth;
345 mhwVeboxSurfaceStateCmdParams->SurfInput.dwHeight = mhwVeboxSurfaceStateCmdParams->SurfOutput.dwHeight =
346 MOS_MIN(inputSurface->dwHeight, ((outputSurface!= nullptr) ? outputSurface->dwHeight : inputSurface->dwHeight));
347 mhwVeboxSurfaceStateCmdParams->SurfInput.dwWidth = mhwVeboxSurfaceStateCmdParams->SurfOutput.dwWidth =
348 MOS_MIN(inputSurface->dwWidth, ((outputSurface != nullptr) ? outputSurface->dwWidth : inputSurface->dwWidth));
349 mhwVeboxSurfaceStateCmdParams->SurfInput.Format = mhwVeboxSurfaceStateCmdParams->SurfOutput.Format = inputSurface->Format;
350
351 MOS_SURFACE inputDetails, outputDetails;
352 MOS_ZeroMemory(&inputDetails, sizeof(inputDetails));
353 MOS_ZeroMemory(&outputDetails, sizeof(outputDetails));
354 inputDetails.Format = Format_Invalid;
355 outputDetails.Format = Format_Invalid;
356
357 if (inputSurface)
358 {
359 VEBOX_COPY_CHK_STATUS_RETURN(m_osInterface->pfnGetResourceInfo(
360 m_osInterface,
361 &inputSurface->OsResource,
362 &inputDetails));
363 }
364
365 if (outputSurface)
366 {
367 VEBOX_COPY_CHK_STATUS_RETURN(m_osInterface->pfnGetResourceInfo(
368 m_osInterface,
369 &outputSurface->OsResource,
370 &outputDetails));
371
372 // Following settings are enabled only when outputSurface is availble
373 inputIsLinearBuffer = (inputDetails.dwHeight == 1) ? true : false;
374 outputIsLinearBuffer = (outputDetails.dwHeight == 1) ? true : false;
375
376 inputWidth = inputSurface->dwWidth;
377 outputWidth = outputSurface->dwWidth;
378
379 if (inputIsLinearBuffer)
380 {
381 bpp = outputDetails.dwPitch / outputDetails.dwWidth;
382 if (outputDetails.dwPitch % outputDetails.dwWidth != 0)
383 {
384 inputWidth = outputDetails.dwPitch / bpp;
385 }
386 }
387 else if (outputIsLinearBuffer)
388 {
389 bpp = inputDetails.dwPitch / inputDetails.dwWidth;
390 if (inputDetails.dwPitch % inputDetails.dwWidth != 0)
391 {
392 outputWidth = inputDetails.dwPitch / bpp;
393 }
394 }
395 else
396 {
397 VEBOX_COPY_NORMALMESSAGE("2D to 2D, no need for bpp setting.");
398 }
399 }
400
401
402 if (inputSurface->dwPitch > 0 &&
403 (inputSurface->Format == Format_P010 ||
404 inputSurface->Format == Format_P016 ||
405 inputSurface->Format == Format_NV12))
406 {
407 mhwVeboxSurfaceStateCmdParams->SurfInput.dwUYoffset = (!inputIsLinearBuffer) ? SURFACE_DW_UY_OFFSET(inputSurface) :
408 inputSurface->dwHeight;
409
410 if (outputSurface)
411 {
412 mhwVeboxSurfaceStateCmdParams->SurfOutput.dwUYoffset = (!outputIsLinearBuffer) ? SURFACE_DW_UY_OFFSET(outputSurface) :
413 outputSurface->dwHeight;
414 }
415 else
416 {
417 mhwVeboxSurfaceStateCmdParams->SurfOutput.dwUYoffset = mhwVeboxSurfaceStateCmdParams->SurfInput.dwUYoffset;
418 }
419 }
420
421 mhwVeboxSurfaceStateCmdParams->SurfInput.rcMaxSrc.left = mhwVeboxSurfaceStateCmdParams->SurfOutput.rcMaxSrc.left = 0;
422 mhwVeboxSurfaceStateCmdParams->SurfInput.rcMaxSrc.right = mhwVeboxSurfaceStateCmdParams->SurfOutput.rcMaxSrc.right = (long)inputSurface->dwWidth;
423 mhwVeboxSurfaceStateCmdParams->SurfInput.rcMaxSrc.top = mhwVeboxSurfaceStateCmdParams->SurfOutput.rcMaxSrc.top = 0;
424 mhwVeboxSurfaceStateCmdParams->SurfInput.rcMaxSrc.bottom = mhwVeboxSurfaceStateCmdParams->SurfOutput.rcMaxSrc.bottom = (long)inputSurface->dwHeight;
425 mhwVeboxSurfaceStateCmdParams->bOutputValid = true;
426
427 // if output surface is null, then Inplace resolve happens
428 if (!outputSurface)
429 {
430 mhwVeboxSurfaceStateCmdParams->SurfInput.TileType = mhwVeboxSurfaceStateCmdParams->SurfOutput.TileType = inputSurface->TileType;
431 mhwVeboxSurfaceStateCmdParams->SurfInput.TileModeGMM = mhwVeboxSurfaceStateCmdParams->SurfOutput.TileModeGMM = inputSurface->TileModeGMM;
432 mhwVeboxSurfaceStateCmdParams->SurfInput.bGMMTileEnabled = mhwVeboxSurfaceStateCmdParams->SurfOutput.bGMMTileEnabled = inputSurface->bGMMTileEnabled;
433 mhwVeboxSurfaceStateCmdParams->SurfOutput.dwPitch = mhwVeboxSurfaceStateCmdParams->SurfInput.dwPitch = inputSurface->dwPitch;
434 mhwVeboxSurfaceStateCmdParams->SurfInput.pOsResource = mhwVeboxSurfaceStateCmdParams->SurfOutput.pOsResource = &(inputSurface->OsResource);
435 mhwVeboxSurfaceStateCmdParams->SurfInput.dwYoffset = mhwVeboxSurfaceStateCmdParams->SurfOutput.dwYoffset = inputSurface->YPlaneOffset.iYOffset;
436 mhwVeboxSurfaceStateCmdParams->SurfInput.dwOffset = mhwVeboxSurfaceStateCmdParams->SurfOutput.dwOffset = inputSurface->dwOffset;
437
438 mhwVeboxSurfaceStateCmdParams->SurfInput.dwCompressionFormat = mhwVeboxSurfaceStateCmdParams->SurfOutput.dwCompressionFormat =
439 inputSurface->CompressionFormat;
440 mhwVeboxSurfaceStateCmdParams->SurfInput.CompressionMode = inputSurface->CompressionMode;
441 mhwVeboxSurfaceStateCmdParams->SurfOutput.CompressionMode = MOS_MMC_DISABLED;
442 }
443 else
444 // double buffer resolve
445 {
446 mhwVeboxSurfaceStateCmdParams->SurfInput.TileType = inputSurface->TileType;
447 mhwVeboxSurfaceStateCmdParams->SurfInput.TileModeGMM = inputSurface->TileModeGMM;
448 mhwVeboxSurfaceStateCmdParams->SurfInput.bGMMTileEnabled = inputSurface->bGMMTileEnabled;
449 mhwVeboxSurfaceStateCmdParams->SurfOutput.TileType = outputSurface->TileType;
450 mhwVeboxSurfaceStateCmdParams->SurfOutput.TileModeGMM = outputSurface->TileModeGMM;
451 mhwVeboxSurfaceStateCmdParams->SurfOutput.bGMMTileEnabled = outputSurface->bGMMTileEnabled;
452 mhwVeboxSurfaceStateCmdParams->SurfInput.dwOffset = inputSurface->dwOffset;
453 mhwVeboxSurfaceStateCmdParams->SurfOutput.dwOffset = outputSurface->dwOffset;
454
455 // When surface is 1D but processed as 2D, fake a min(pitch, width) is needed as the pitch API passed may less surface width in 1D surface
456 mhwVeboxSurfaceStateCmdParams->SurfInput.dwPitch = (inputIsLinearBuffer) ?
457 MOS_MIN(inputWidth * bpp, inputSurface->dwPitch) : inputSurface->dwPitch;
458 mhwVeboxSurfaceStateCmdParams->SurfOutput.dwPitch = (outputIsLinearBuffer) ?
459 MOS_MIN(outputWidth * bpp, outputSurface->dwPitch) : outputSurface->dwPitch;
460 mhwVeboxSurfaceStateCmdParams->SurfInput.pOsResource = &(inputSurface->OsResource);
461 mhwVeboxSurfaceStateCmdParams->SurfOutput.pOsResource = &(outputSurface->OsResource);
462 mhwVeboxSurfaceStateCmdParams->SurfInput.dwYoffset = inputSurface->YPlaneOffset.iYOffset;
463 mhwVeboxSurfaceStateCmdParams->SurfOutput.dwYoffset = outputSurface->YPlaneOffset.iYOffset;
464 mhwVeboxSurfaceStateCmdParams->SurfInput.dwCompressionFormat = inputSurface->CompressionFormat;
465 mhwVeboxSurfaceStateCmdParams->SurfOutput.dwCompressionFormat = outputSurface->CompressionFormat;
466 mhwVeboxSurfaceStateCmdParams->SurfInput.CompressionMode = inputSurface->CompressionMode;
467 mhwVeboxSurfaceStateCmdParams->SurfOutput.CompressionMode = outputSurface->CompressionMode;
468 }
469
470 return eStatus;
471 }
472
InitCommandBuffer(PMOS_COMMAND_BUFFER cmdBuffer)473 MOS_STATUS VeboxCopyStateNext::InitCommandBuffer(PMOS_COMMAND_BUFFER cmdBuffer)
474 {
475 PMOS_INTERFACE pOsInterface;
476 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
477 uint32_t iRemaining;
478 RENDERHAL_GENERIC_PROLOG_PARAMS GenericPrologParams = {};
479 PMOS_RESOURCE gpuStatusBuffer = nullptr;
480
481 //---------------------------------------------
482 VEBOX_COPY_CHK_NULL_RETURN(cmdBuffer);
483 VEBOX_COPY_CHK_NULL_RETURN(m_osInterface);
484 //---------------------------------------------
485
486 eStatus = MOS_STATUS_SUCCESS;
487 pOsInterface = m_osInterface;
488 MOS_ZeroMemory(&GenericPrologParams, sizeof(RENDERHAL_GENERIC_PROLOG_PARAMS));
489
490 MOS_GPU_CONTEXT gpuContext = m_osInterface->pfnGetGpuContext(m_osInterface);
491
492 #ifndef EMUL
493 if (pOsInterface->bEnableKmdMediaFrameTracking)
494 {
495 // Get GPU Status buffer
496 VEBOX_COPY_CHK_STATUS_RETURN(pOsInterface->pfnGetGpuStatusBufferResource(pOsInterface, gpuStatusBuffer));
497 VEBOX_COPY_CHK_NULL_RETURN(gpuStatusBuffer);
498 // Register the buffer
499 VEBOX_COPY_CHK_STATUS_RETURN(pOsInterface->pfnRegisterResource(pOsInterface, gpuStatusBuffer, true, true));
500
501 GenericPrologParams.bEnableMediaFrameTracking = true;
502 GenericPrologParams.presMediaFrameTrackingSurface = gpuStatusBuffer;
503 GenericPrologParams.dwMediaFrameTrackingTag = pOsInterface->pfnGetGpuStatusTag(pOsInterface, pOsInterface->CurrentGpuContextOrdinal);
504 GenericPrologParams.dwMediaFrameTrackingAddrOffset = pOsInterface->pfnGetGpuStatusTagOffset(pOsInterface, pOsInterface->CurrentGpuContextOrdinal);
505
506 // Increment GPU Status Tag
507 pOsInterface->pfnIncrementGpuStatusTag(pOsInterface, pOsInterface->CurrentGpuContextOrdinal);
508 }
509 #endif
510
511 if (GenericPrologParams.bEnableMediaFrameTracking)
512 {
513 VEBOX_COPY_CHK_NULL_RETURN(GenericPrologParams.presMediaFrameTrackingSurface);
514 cmdBuffer->Attributes.bEnableMediaFrameTracking = GenericPrologParams.bEnableMediaFrameTracking;
515 cmdBuffer->Attributes.dwMediaFrameTrackingTag = GenericPrologParams.dwMediaFrameTrackingTag;
516 cmdBuffer->Attributes.dwMediaFrameTrackingAddrOffset = GenericPrologParams.dwMediaFrameTrackingAddrOffset;
517 cmdBuffer->Attributes.resMediaFrameTrackingSurface = GenericPrologParams.presMediaFrameTrackingSurface;
518 }
519
520 // initialize command buffer attributes
521 cmdBuffer->Attributes.bTurboMode = false;
522 cmdBuffer->Attributes.bMediaPreemptionEnabled = false;
523 cmdBuffer->Attributes.dwMediaFrameTrackingAddrOffset = 0;
524
525 MHW_GENERIC_PROLOG_PARAMS genericPrologParams;
526 MOS_ZeroMemory(&genericPrologParams, sizeof(genericPrologParams));
527 genericPrologParams.pOsInterface = m_osInterface;
528 genericPrologParams.bMmcEnabled = true;
529
530 VEBOX_COPY_CHK_STATUS_RETURN(Mhw_SendGenericPrologCmdNext(
531 cmdBuffer,
532 &genericPrologParams,
533 m_miItf));
534
535 return eStatus;
536 }
537
IsVeCopySupportedFormat(MOS_FORMAT format)538 bool VeboxCopyStateNext::IsVeCopySupportedFormat(MOS_FORMAT format)
539 {
540 if (format == Format_R10G10B10A2 ||
541 format == Format_B10G10R10A2 ||
542 format == Format_A8R8G8B8 ||
543 format == Format_A8B8G8R8 ||
544 format == Format_X8R8G8B8 ||
545 format == Format_X8B8G8R8 ||
546 IS_RGB64_FLOAT_FORMAT(format) ||
547
548 format == Format_AYUV ||
549 format == Format_Y410 ||
550 format == Format_Y416 ||
551 format == Format_Y210 ||
552 format == Format_Y216 ||
553 format == Format_YUY2 ||
554 format == Format_NV12 ||
555 format == Format_P010 ||
556 format == Format_P016 ||
557
558 format == Format_A8 ||
559 format == Format_Y8 ||
560 format == Format_L8 ||
561 format == Format_P8 ||
562 format == Format_Y16U)
563 {
564 return true;
565 }
566 else
567 {
568 VEBOX_COPY_NORMALMESSAGE("Unsupported format '0x%08x' for VEBOX copy.", format);
569 return false;
570 }
571 }
572
AdjustSurfaceFormat(MOS_SURFACE & surface)573 void VeboxCopyStateNext::AdjustSurfaceFormat(MOS_SURFACE &surface)
574 {
575 if (surface.Format == Format_R10G10B10A2 ||
576 surface.Format == Format_B10G10R10A2 ||
577 surface.Format == Format_Y410 ||
578 surface.Format == Format_Y210)
579 {
580 // RGB10 not supported without IECP. Re-map RGB10/RGB10 as AYUV
581 // Y410/Y210 has HW issue. Remap to AYUV.
582 surface.Format = Format_AYUV;
583 }
584 else if (surface.Format == Format_A8)
585 {
586 surface.Format = Format_P8;
587 }
588 }
589
CreateGpuContext(PMOS_INTERFACE pOsInterface,MOS_GPU_CONTEXT VeboxGpuContext,MOS_GPU_NODE VeboxGpuNode)590 MOS_STATUS VeboxCopyStateNext::CreateGpuContext(
591 PMOS_INTERFACE pOsInterface,
592 MOS_GPU_CONTEXT VeboxGpuContext,
593 MOS_GPU_NODE VeboxGpuNode)
594 {
595 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
596
597 MHW_CHK_NULL_RETURN(pOsInterface);
598
599 if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(pOsInterface))
600 {
601 MOS_GPUCTX_CREATOPTIONS createOption;
602 // Create VEBOX/VEBOX2 Context
603 MHW_CHK_STATUS_RETURN(pOsInterface->pfnCreateGpuContext(
604 pOsInterface,
605 VeboxGpuContext,
606 VeboxGpuNode,
607 &createOption));
608 }
609 else
610 {
611 MOS_GPUCTX_CREATOPTIONS_ENHANCED createOptionenhanced;
612 // vebox copy always uses 1 vebox to copy each frame.
613 createOptionenhanced.LRCACount = 1;
614
615 // Create virtual engine context for vebox
616 MHW_CHK_STATUS_RETURN(pOsInterface->pfnCreateGpuContext(
617 pOsInterface,
618 VeboxGpuContext,
619 VeboxGpuNode,
620 &createOptionenhanced));
621 }
622
623 return eStatus;
624 }