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(&params, 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 }