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