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