1 /*
2 * Copyright (c) 2020, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file       media_render_copy_next.cpp
24 //! \brief      render copy implement file
25 //! \details    render copy implement file
26 //!
27 
28 #include "media_render_copy_next.h"
29 #include "media_interfaces_mhw_next.h"
30 #include "media_render_common.h"
31 
32 //!
33 //! \brief Initialize MHW Kernel Param struct for loading Kernel
34 //!
35 #define INIT_MHW_KERNEL_PARAM(MhwKernelParam, _pKernelEntry)                        \
36     do                                                                              \
37     {                                                                               \
38         MOS_ZeroMemory(&(MhwKernelParam), sizeof(MhwKernelParam));                  \
39         (MhwKernelParam).pBinary  = (_pKernelEntry)->pBinary;                       \
40         (MhwKernelParam).iSize    = (_pKernelEntry)->iSize;                         \
41         (MhwKernelParam).iKUID    = (_pKernelEntry)->iKUID;                         \
42         (MhwKernelParam).iKCID    = (_pKernelEntry)->iKCID;                         \
43     } while(0)
44 
45 
RenderCopyStateNext(PMOS_INTERFACE osInterface,MhwInterfacesNext * mhwInterfaces)46 RenderCopyStateNext::RenderCopyStateNext(PMOS_INTERFACE osInterface, MhwInterfacesNext *mhwInterfaces) :
47     m_osInterface(osInterface),
48     m_mhwInterfaces(mhwInterfaces)
49 {
50     if (nullptr == osInterface)
51     {
52         MCPY_ASSERTMESSAGE("osInterface is nullptr");
53         return;
54     }
55     m_RenderData.pKernelParam = (PRENDERHAL_KERNEL_PARAM)g_rendercopy_KernelParam;
56     Mos_SetVirtualEngineSupported(osInterface, true);
57     osInterface->pfnVirtualEngineSupported(osInterface, true, false);
58 
59     MOS_NULL_RENDERING_FLAGS        NullRenderingFlags;
60     NullRenderingFlags = osInterface->pfnGetNullHWRenderFlags(osInterface);
61 
62     m_bNullHwRenderCopy =
63      NullRenderingFlags.VPComp ||
64      NullRenderingFlags.VPGobal;
65 }
66 
~RenderCopyStateNext()67 RenderCopyStateNext:: ~RenderCopyStateNext()
68 {
69     if (m_renderHal != nullptr)
70     {
71         if (m_renderHal->pfnDestroy)
72         {
73             MOS_STATUS eStatus = m_renderHal->pfnDestroy(m_renderHal);
74             if (eStatus != MOS_STATUS_SUCCESS)
75             {
76                 MCPY_ASSERTMESSAGE("Failed to destroy RenderHal, eStatus:%d.\n", eStatus);
77             }
78         }
79        MOS_FreeMemAndSetNull(m_renderHal);
80     }
81 
82     if (m_cpInterface != nullptr)
83     {
84         if (m_osInterface)
85         {
86             m_osInterface->pfnDeleteMhwCpInterface(m_cpInterface);
87             m_cpInterface = nullptr;
88         }
89         else
90         {
91             MCPY_ASSERTMESSAGE("Failed to destroy cpInterface.");
92         }
93     }
94 
95     // Destroy Kernel DLL objects (cache, hash table, states)
96     if (m_pKernelDllState)
97     {
98        KernelDll_ReleaseStates(m_pKernelDllState);
99        m_pKernelBin = nullptr;
100     }
101 }
102 
Initialize()103 MOS_STATUS RenderCopyStateNext::Initialize()
104 {
105     RENDERHAL_SETTINGS      RenderHalSettings;
106 
107     MCPY_CHK_NULL_RETURN(m_osInterface);
108 
109     m_renderHal = (PRENDERHAL_INTERFACE)MOS_AllocAndZeroMemory(sizeof(*m_renderHal));
110     MCPY_CHK_NULL_RETURN(m_renderHal);
111     MCPY_CHK_STATUS_RETURN(RenderHal_InitInterface(
112         m_renderHal,
113         &m_cpInterface,
114         m_osInterface));
115 
116     // Allocate and initialize HW states
117     RenderHalSettings.iMediaStates = 32;
118     MCPY_CHK_STATUS_RETURN(m_renderHal->pfnInitialize(m_renderHal, &RenderHalSettings));
119 
120     m_renderHal->sseuTable              = defaultSSEUTable;
121     m_renderHal->forceDisablePreemption = true;
122 
123     return MOS_STATUS_SUCCESS;
124 }
125 
GetBytesPerPixelPerPlane(MOS_FORMAT Format)126 int32_t RenderCopyStateNext::GetBytesPerPixelPerPlane(
127     MOS_FORMAT        Format)
128 {
129     int32_t     iBytePerPixelPerPlane = 0;
130 
131     switch(Format)
132     {
133     case Format_NV12:
134     case Format_RGBP:
135         iBytePerPixelPerPlane = 1;
136         break;
137     case Format_YUY2:
138     case Format_P010:
139     case Format_P016:
140         iBytePerPixelPerPlane = 2;
141         break;
142     case Format_Y210:
143     case Format_Y216:
144     case Format_Y410:
145     case Format_AYUV:
146     case Format_A8R8G8B8:
147         iBytePerPixelPerPlane = 4;
148         break;
149     case Format_Y416:
150         iBytePerPixelPerPlane = 8;
151         break;
152     default:
153         MCPY_ASSERTMESSAGE("can't support formats %d for render copy", Format);
154         break;
155     }
156 
157     return iBytePerPixelPerPlane;
158 }
159 
SetupKernel(int32_t iKDTIndex)160 MOS_STATUS RenderCopyStateNext::SetupKernel(
161     int32_t iKDTIndex)
162 {
163     Kdll_CacheEntry* pCacheEntryTable;                              // Kernel Cache Entry table
164     int32_t                     iKUID = 0;                                     // Kernel Unique ID
165     int32_t                     iInlineLength;                                  // Inline data length
166     int32_t                     iTotalRows;                                     // Total number of row in statistics surface
167     int32_t                     iTotalColumns;                                  // Total number of columns in statistics surface
168     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;                   // Return code
169     uint32_t                    dwKernelBinSize;
170     PMEDIACOPY_RENDER_DATA      pRenderData = &m_RenderData;
171     const void* pcKernelBin = nullptr;
172 
173     MCPY_CHK_NULL_RETURN(pRenderData);
174     if (iKDTIndex == KERNEL_CopyKernel_1D_to_2D_NV12)
175     {
176         iKUID = IDR_VP_CopyKernel_1D_to_2D_NV12_genx;
177     }
178     else if (iKDTIndex == KERNEL_CopyKernel_2D_to_2D_NV12)
179     {
180         iKUID = IDR_VP_CopyKernel_2D_to_2D_NV12_genx;
181     }
182     else if (iKDTIndex == KERNEL_CopyKernel_2D_to_1D_NV12)
183     {
184         iKUID = IDR_VP_CopyKernel_2D_to_1D_NV12_genx;
185     }
186     else if (iKDTIndex == KERNEL_CopyKernel_1D_to_2D_Planar)
187     {
188         iKUID = IDR_VP_CopyKernel_1D_to_2D_RGBP_genx;
189     }
190     else if (iKDTIndex == KERNEL_CopyKernel_2D_to_2D_Planar)
191     {
192         iKUID = IDR_VP_CopyKernel_2D_to_2D_RGBP_genx;
193     }
194     else if (iKDTIndex == KERNEL_CopyKernel_2D_to_1D_Planar)
195     {
196         iKUID = IDR_VP_CopyKernel_2D_to_1D_RGBP_genx;
197     }
198     else if (iKDTIndex == KERNEL_CopyKernel_1D_to_2D_Packed)
199     {
200         iKUID = IDR_VP_CopyKernel_1D_to_2D_genx;
201     }
202     else if (iKDTIndex == KERNEL_CopyKernel_2D_to_2D_Packed)
203     {
204         iKUID = IDR_VP_CopyKernel_2D_to_2D_genx;
205     }
206     else if (iKDTIndex == KERNEL_CopyKernel_2D_to_1D_Packed)
207     {
208         iKUID = IDR_VP_CopyKernel_2D_to_1D_genx;
209     }
210     else
211     {
212         MCPY_ASSERTMESSAGE("Can't find the right kernel.");
213         return MOS_STATUS_UNKNOWN;
214     }
215 
216     pcKernelBin = m_KernelBin;
217     dwKernelBinSize = m_KernelBinSize;
218 
219     if (nullptr == m_pKernelBin)
220     {
221         m_pKernelBin = MOS_AllocMemory(dwKernelBinSize);
222     }
223 
224     MCPY_CHK_NULL_RETURN(m_pKernelBin);
225     MOS_SecureMemcpy(m_pKernelBin,
226         dwKernelBinSize,
227         pcKernelBin,
228         dwKernelBinSize);
229 
230     // Allocate KDLL state (Kernel Dynamic Linking)
231     if (nullptr == m_pKernelDllState)
232     {
233         m_pKernelDllState = KernelDll_AllocateStates(
234             m_pKernelBin,
235             dwKernelBinSize,
236             nullptr,
237             0,
238             nullptr,
239             nullptr);
240     }
241     if (nullptr == m_pKernelDllState)
242     {
243         MCPY_ASSERTMESSAGE("Failed to allocate KDLL state.");
244         if (m_pKernelBin)
245         {
246             MOS_SafeFreeMemory(m_pKernelBin);
247             m_pKernelBin = nullptr;
248         }
249         return MOS_STATUS_NULL_POINTER;
250     }
251     pCacheEntryTable =
252         m_pKernelDllState->ComponentKernelCache.pCacheEntries;
253 
254     // Set the Kernel Parameters
255     pRenderData->pKernelParam = (PRENDERHAL_KERNEL_PARAM)&g_rendercopy_KernelParam[iKDTIndex];
256     pRenderData->PerfTag = VPHAL_NONE;
257 
258     // Set Kernel entry
259     pRenderData->KernelEntry.iKUID = iKUID;
260     pRenderData->KernelEntry.iKCID = -1;
261     pRenderData->KernelEntry.iSize = pCacheEntryTable[iKUID].iSize;
262     pRenderData->KernelEntry.pBinary = pCacheEntryTable[iKUID].pBinary;
263 
264     return eStatus;
265 }
266 
SubmitCMD()267 MOS_STATUS RenderCopyStateNext::SubmitCMD()
268 {
269     PRENDERHAL_INTERFACE        pRenderHal;
270     PMOS_INTERFACE              pOsInterface;
271     MHW_KERNEL_PARAM            MhwKernelParam;
272     int32_t                     iKrnAllocation;
273     int32_t                     iCurbeOffset;
274     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
275 
276     PMEDIACOPY_RENDER_DATA      pRenderData = &m_RenderData;
277     MHW_WALKER_PARAMS           WalkerParams = {0};
278     PMHW_WALKER_PARAMS          pWalkerParams = nullptr;
279     MHW_GPGPU_WALKER_PARAMS     ComputeWalkerParams = {0};
280     PMHW_GPGPU_WALKER_PARAMS    pComputeWalkerParams = nullptr;
281     MOS_GPUCTX_CREATOPTIONS_ENHANCED createOption = {};
282 
283     pRenderHal = m_renderHal;
284     pOsInterface = m_osInterface;
285     // no gpucontext will be created if the gpu context has been created before.
286     MCPY_CHK_STATUS_RETURN(pOsInterface->pfnCreateGpuContext(
287         m_osInterface,
288         MOS_GPU_CONTEXT_COMPUTE,
289         MOS_GPU_NODE_COMPUTE,
290         &createOption));
291 
292     // Register context with the Batch Buffer completion event
293     MCPY_CHK_STATUS_RETURN(m_osInterface->pfnRegisterBBCompleteNotifyEvent(
294         m_osInterface,
295         MOS_GPU_CONTEXT_COMPUTE));
296 
297     // Set GPU Context to Render Engine
298     MCPY_CHK_STATUS_RETURN(pOsInterface->pfnSetGpuContext(pOsInterface, MOS_GPU_CONTEXT_COMPUTE));
299 
300     // Reset allocation list and house keeping
301     m_osInterface->pfnResetOsStates(pOsInterface);
302 
303     // Register the resource of GSH
304     MCPY_CHK_STATUS_RETURN(pRenderHal->pfnReset(pRenderHal));
305 
306     // Set copy kernel
307     SetupKernel(m_currKernelId);
308 
309     //----------------------------------
310     // Allocate and reset media state
311     //----------------------------------
312     pRenderData->pMediaState = pRenderHal->pfnAssignMediaState(pRenderHal, RENDERHAL_COMPONENT_RENDER_COPY);
313     MCPY_CHK_NULL_RETURN(pRenderData->pMediaState);
314 
315     // Allocate and reset SSH instance
316     MCPY_CHK_STATUS_RETURN(pRenderHal->pfnAssignSshInstance(pRenderHal));
317 
318     // Assign and Reset Binding Table
319     MCPY_CHK_STATUS_RETURN(pRenderHal->pfnAssignBindingTable(
320         pRenderHal,
321         &pRenderData->iBindingTable));
322 
323     // Setup surface states
324     MCPY_CHK_STATUS_RETURN(SetupSurfaceStates())
325 
326         // load static data
327         MCPY_CHK_STATUS_RETURN(LoadStaticData(
328             &iCurbeOffset));
329 
330     //----------------------------------
331     // Setup VFE State params. Each Renderer MUST call pfnSetVfeStateParams().
332     //----------------------------------
333     MCPY_CHK_STATUS_RETURN(pRenderHal->pfnSetVfeStateParams(
334         pRenderHal,
335         MEDIASTATE_DEBUG_COUNTER_FREE_RUNNING,
336         pRenderData->pKernelParam->Thread_Count,
337         pRenderData->iCurbeLength,
338         pRenderData->iInlineLength,
339         nullptr));
340 
341     //----------------------------------
342     // Load kernel to GSH
343     //----------------------------------
344     INIT_MHW_KERNEL_PARAM(MhwKernelParam, &pRenderData->KernelEntry);
345     iKrnAllocation = pRenderHal->pfnLoadKernel(
346         pRenderHal,
347         pRenderData->pKernelParam,
348         &MhwKernelParam,
349         nullptr);
350     if (iKrnAllocation < 0)
351     {
352         eStatus = MOS_STATUS_UNKNOWN;
353         return eStatus;
354     }
355 
356     //----------------------------------
357     // Allocate Media ID, link to kernel
358     //----------------------------------
359     pRenderData->iMediaID = pRenderHal->pfnAllocateMediaID(
360         pRenderHal,
361         iKrnAllocation,
362         pRenderData->iBindingTable,
363         iCurbeOffset,
364         pRenderData->pKernelParam->CURBE_Length << 5,
365         0,
366         nullptr);
367     if (pRenderData->iMediaID < 0)
368     {
369         eStatus = MOS_STATUS_UNKNOWN;
370         return eStatus;
371     }
372 
373     // Set Perf Tag
374     pOsInterface->pfnResetPerfBufferID(pOsInterface);
375     m_osInterface->pfnSetPerfTag(m_osInterface, RENDER_COPY);
376 
377     // Setup Compute Walker
378     pWalkerParams = nullptr;
379     pComputeWalkerParams = &ComputeWalkerParams;
380 
381     RenderCopyComputerWalker(
382         &ComputeWalkerParams);
383 
384     // Submit all states to render the kernel
385     //VpHal_RndrCommonSubmitCommands(
386     MediaRenderCommon::EukernelSubmitCommands(
387         pRenderHal,
388         nullptr,
389         m_bNullHwRenderCopy,
390         pWalkerParams,
391         pComputeWalkerParams,
392         (VpKernelID)kernelRenderCopy,
393         true);
394 
395     return eStatus;
396 }
397 
GetCurentKernelID()398 MOS_STATUS RenderCopyStateNext::GetCurentKernelID( )
399 {
400     int32_t iBytePerPixelPerPlane = GetBytesPerPixelPerPlane(m_Source.Format);
401 
402     if ((iBytePerPixelPerPlane < 1) || (iBytePerPixelPerPlane > 8))
403     {
404         MCPY_ASSERTMESSAGE("GetCurentKernelID wrong pixel size.");
405         return MOS_STATUS_INVALID_PARAMETER;
406     }
407 
408     // This scheme is temporary
409     // for a !MOS_TILE_LINEAR plane surface, it is 2D surface.
410     // for a MOS_TILE_LINEAR plane surface, if (dwWidth * bytes_per_pixel < dwPitch) it is 2D surface
411     // if (dwWidth * bytes_per_pixel == dwPitch) it is a 1D surface.
412 
413     if ((m_Source.Format == Format_NV12) || (m_Source.Format == Format_P010) || (m_Source.Format == Format_P016))
414     {
415         if (m_Source.TileType == MOS_TILE_LINEAR && m_Target.TileType != MOS_TILE_LINEAR)
416         {
417             m_currKernelId = KERNEL_CopyKernel_1D_to_2D_NV12;
418         }
419         else if (m_Source.TileType != MOS_TILE_LINEAR && m_Target.TileType == MOS_TILE_LINEAR)
420         {
421             m_currKernelId = KERNEL_CopyKernel_2D_to_1D_NV12;
422         }
423         else if (m_Source.TileType != MOS_TILE_LINEAR && m_Target.TileType != MOS_TILE_LINEAR)
424         {
425             m_currKernelId = KERNEL_CopyKernel_2D_to_2D_NV12;
426         }
427         else
428         {
429              m_currKernelId = KERNEL_CopyKernel_MAX;
430              MCPY_ASSERTMESSAGE("Can't find right kernel to support, pls help to check input parameters.");
431              return MOS_STATUS_INVALID_PARAMETER;
432         }
433     }
434     else if (m_Source.Format == Format_RGBP)
435     {
436         if (m_Source.TileType == MOS_TILE_LINEAR && m_Target.TileType != MOS_TILE_LINEAR)
437         {
438             m_currKernelId = KERNEL_CopyKernel_1D_to_2D_Planar;
439         }
440         else if (m_Source.TileType != MOS_TILE_LINEAR && m_Target.TileType == MOS_TILE_LINEAR)
441         {
442             m_currKernelId = KERNEL_CopyKernel_2D_to_1D_Planar;
443         }
444         else if (m_Source.TileType != MOS_TILE_LINEAR && m_Target.TileType != MOS_TILE_LINEAR)
445         {
446             m_currKernelId = KERNEL_CopyKernel_2D_to_2D_Planar;
447         }
448         else
449         {
450             m_currKernelId = KERNEL_CopyKernel_MAX;
451             MCPY_ASSERTMESSAGE("kernel can't support it.");
452             return MOS_STATUS_INVALID_PARAMETER;
453         }
454     }
455     else if ((m_Source.Format == Format_YUY2) || (m_Source.Format == Format_Y210) || (m_Source.Format == Format_Y216)
456               || (m_Source.Format == Format_AYUV) || (m_Source.Format == Format_Y410) || (m_Source.Format == Format_Y416)
457               || (m_Source.Format == Format_A8R8G8B8))
458     {
459         if (m_Source.TileType == MOS_TILE_LINEAR && m_Target.TileType != MOS_TILE_LINEAR)
460         {
461             m_currKernelId = KERNEL_CopyKernel_1D_to_2D_Packed;
462         }
463         else if (m_Source.TileType != MOS_TILE_LINEAR && m_Target.TileType == MOS_TILE_LINEAR)
464         {
465             m_currKernelId = KERNEL_CopyKernel_2D_to_1D_Packed;
466         }
467         else if (m_Source.TileType != MOS_TILE_LINEAR && m_Target.TileType != MOS_TILE_LINEAR)
468         {
469             m_currKernelId = KERNEL_CopyKernel_2D_to_2D_Packed;
470         }
471         else
472         {
473              m_currKernelId = KERNEL_CopyKernel_MAX;
474              MCPY_ASSERTMESSAGE("kernel can't support it.");
475              return MOS_STATUS_INVALID_PARAMETER;
476         }
477 
478     }
479     MCPY_NORMALMESSAGE("Used Render copy and currentKernel id = %d.", m_currKernelId);
480     return MOS_STATUS_SUCCESS;
481 }
482 
483 //!
484 //! \brief    setup surface states
485 //! \details  Setup surface states for fast 1toN
486 //! \return   MOS_STATUS
487 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
488 //!
SetupSurfaceStates()489 MOS_STATUS RenderCopyStateNext::SetupSurfaceStates()
490 {
491     RENDERHAL_SURFACE_STATE_PARAMS  SurfaceParams;
492     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
493     uint32_t                        index;
494     uint32_t                        width  = 0;
495     MOS_FORMAT                      format = Format_NV12;
496     int32_t                         iBTEntry;
497     PRENDERHAL_INTERFACE            pRenderHal  = m_renderHal;
498     PMEDIACOPY_RENDER_DATA          pRenderData = &m_RenderData;
499     RENDERHAL_SURFACE               RenderHalSource = {};  // source for mhw
500     RENDERHAL_SURFACE               RenderHalTarget = {};
501     MCPY_CHK_NULL_RETURN(pRenderHal);
502     MCPY_CHK_NULL_RETURN(pRenderData);
503     // Source surface
504     MOS_ZeroMemory(&SurfaceParams, sizeof(SurfaceParams));
505 
506     pRenderData->SurfMemObjCtl.SourceSurfMemObjCtl =
507          pRenderHal->pOsInterface->pfnCachePolicyGetMemoryObject(
508          MOS_MP_RESOURCE_USAGE_SurfaceState_RCS,
509          pRenderHal->pOsInterface->pfnGetGmmClientContext(pRenderHal->pOsInterface)).DwordValue;
510 
511     pRenderData->SurfMemObjCtl.TargetSurfMemObjCtl = pRenderData->SurfMemObjCtl.SourceSurfMemObjCtl;
512 
513     SurfaceParams.bAVS              = false;
514     SurfaceParams.Boundary          = RENDERHAL_SS_BOUNDARY_SRCRECT;
515     SurfaceParams.isOutput     = false;
516     SurfaceParams.MemObjCtl         = pRenderData->SurfMemObjCtl.SourceSurfMemObjCtl;
517 
518     SurfaceParams.Type              = RENDERHAL_SURFACE_TYPE_G10;
519     SurfaceParams.bWidthInDword_Y   = false;
520     SurfaceParams.bWidthInDword_UV  = false;
521     SurfaceParams.bWidth16Align     = false;
522 
523     if (Format_NV12 == m_Target.Format)
524     {
525         // set NV12 as 2 plane because render copy only uses DP reading&writing.
526         RenderHalSource.SurfType = RENDERHAL_SURF_OUT_RENDERTARGET;
527         RenderHalTarget.SurfType = RENDERHAL_SURF_OUT_RENDERTARGET;
528     }
529 
530     if (m_currKernelId == KERNEL_CopyKernel_1D_to_2D_NV12
531         || m_currKernelId == KERNEL_CopyKernel_1D_to_2D_Planar
532         || m_currKernelId == KERNEL_CopyKernel_1D_to_2D_Packed)
533     {
534         format = m_Source.Format;
535         width = m_Source.dwWidth;
536         m_Source.Format = Format_RAW;
537 
538         if ((format == Format_NV12) || (format == Format_P010) || (format == Format_P016))
539         {
540            m_Source.dwWidth = (m_Source.dwHeight * m_Source.dwPitch) * 3 / 2;
541         }
542         else if (format == Format_RGBP)
543         {
544            m_Source.dwWidth = (m_Source.dwHeight * m_Source.dwPitch) * 3;
545         }
546         else if ((format == Format_YUY2) || (format == Format_Y210) || (format == Format_Y216)
547                  || (format == Format_AYUV) || (format == Format_Y410) || (format == Format_Y416)
548                  || (format == Format_A8R8G8B8))
549         {
550            m_Source.dwWidth = m_Source.dwHeight * m_Source.dwPitch;
551         }
552 
553         m_Source.dwWidth = MOS_ALIGN_CEIL(m_Source.dwWidth, 128);
554         //1D surfaces
555         MCPY_CHK_STATUS_RETURN(MediaRenderCommon::Set1DSurfaceForHwAccess(
556              pRenderHal,
557              &m_Source,
558              &RenderHalSource,
559              &SurfaceParams,
560              pRenderData->iBindingTable,
561              RENDERCOPY_SRC_INDEX,
562              false));
563         m_Source.Format = format;
564         m_Source.dwWidth = width;
565     }
566     else {
567         //2D surfaces
568         MCPY_CHK_STATUS_RETURN(MediaRenderCommon::Set2DSurfaceForHwAccess(
569             pRenderHal,
570             &m_Source,
571             &RenderHalSource,
572             &SurfaceParams,
573             pRenderData->iBindingTable,
574             RENDERCOPY_SRC_INDEX,
575             false));
576     }
577 
578     // Target surface
579     SurfaceParams.MemObjCtl         = pRenderData->SurfMemObjCtl.TargetSurfMemObjCtl;
580     SurfaceParams.Type              = pRenderHal->SurfaceTypeDefault;
581     SurfaceParams.isOutput     = true;
582     SurfaceParams.bAVS              = false;
583     SurfaceParams.Boundary          = RENDERHAL_SS_BOUNDARY_DSTRECT;
584 
585     if (m_currKernelId == KERNEL_CopyKernel_2D_to_1D_NV12
586         || m_currKernelId == KERNEL_CopyKernel_2D_to_1D_Planar
587         || m_currKernelId == KERNEL_CopyKernel_2D_to_1D_Packed)
588     {
589         format = m_Target.Format;
590         width = m_Target.dwWidth;
591         m_Target.Format = Format_RAW;
592 
593           if ((format == Format_NV12) || (format == Format_P010) || (format == Format_P016))
594           {
595              m_Target.dwWidth = (m_Target.dwHeight * m_Target.dwPitch) * 3 / 2;
596           }
597           else if (format == Format_RGBP)
598           {
599              m_Target.dwWidth = (m_Target.dwHeight * m_Target.dwPitch) * 3;
600           }
601           else if ((format == Format_YUY2) || (format == Format_Y210) || (format == Format_Y216)
602                    || (format == Format_AYUV) || (format == Format_Y410) || (format == Format_Y416)
603                    || (format == Format_A8R8G8B8))
604           {
605              m_Target.dwWidth = m_Target.dwHeight * m_Target.dwPitch;
606           }
607 
608         m_Target.dwWidth = MOS_ALIGN_CEIL(m_Target.dwWidth, 128);
609 
610         //1D surface.
611         MCPY_CHK_STATUS_RETURN(MediaRenderCommon::Set1DSurfaceForHwAccess(
612             pRenderHal,
613             &m_Target,
614             &RenderHalTarget,
615             &SurfaceParams,
616             pRenderData->iBindingTable,
617             RENDERCOPY_DST_INDEX,
618             true));
619         m_Target.Format = format;
620         m_Target.dwWidth = width;
621     }
622     else
623     {
624         //2D surface.
625         MCPY_CHK_STATUS_RETURN(MediaRenderCommon::Set2DSurfaceForHwAccess(
626             pRenderHal,
627             &m_Target,
628             &RenderHalTarget,
629             &SurfaceParams,
630             pRenderData->iBindingTable,
631             RENDERCOPY_DST_INDEX,
632             true));
633 
634     }
635 
636     return eStatus;
637 }
638 
639 
LoadStaticData(int32_t * piCurbeOffset)640 MOS_STATUS RenderCopyStateNext::LoadStaticData(
641     int32_t*                        piCurbeOffset)
642 {
643     DP_RENDERCOPY_NV12_STATIC_DATA          WalkerNV12Static;
644     DP_RENDERCOPY_RGBP_STATIC_DATA          WalkerPlanarStatic;
645     DP_RENDERCOPY_PACKED_STATIC_DATA        WalkerSinglePlaneStatic;
646 
647     MOS_STATUS                              eStatus = MOS_STATUS_SUCCESS;
648     int32_t                                 iCurbeLength = 0;
649     int32_t                                 iBytePerPixelPerPlane = GetBytesPerPixelPerPlane(m_Target.Format);
650     PRENDERHAL_INTERFACE                    pRenderHal  = m_renderHal;
651     PMEDIACOPY_RENDER_DATA                  pRenderData = &m_RenderData;
652 
653     MCPY_CHK_NULL_RETURN(pRenderHal);
654     MCPY_CHK_NULL_RETURN(pRenderData);
655     if ((iBytePerPixelPerPlane < 1) || (iBytePerPixelPerPlane > 8))
656     {
657         MCPY_ASSERTMESSAGE("LoadStaticData wrong pixel size.");
658         return MOS_STATUS_INVALID_PARAMETER;
659     }
660 
661     int32_t srcResourceOffset = (int32_t)(m_Source.OsResource.pGmmResInfo->GetPlanarXOffset(GMM_NO_PLANE));
662     int32_t dstResourceOffset = (int32_t)(m_Target.OsResource.pGmmResInfo->GetPlanarXOffset(GMM_NO_PLANE));
663 
664     if (srcResourceOffset)
665     {
666         m_Source.dwOffset -= srcResourceOffset;
667     }
668 
669     if (dstResourceOffset)
670     {
671         m_Target.dwOffset -= dstResourceOffset;
672     }
673 
674     if ((m_Target.Format == Format_NV12) || ((m_Target.Format == Format_P010) || (m_Target.Format == Format_P016)))
675     {
676         // Set relevant static data
677         MOS_ZeroMemory(&WalkerNV12Static, sizeof(DP_RENDERCOPY_NV12_STATIC_DATA));
678 
679         WalkerNV12Static.DW0.Inputsurfaceindex = RENDERCOPY_SRC_INDEX;
680         WalkerNV12Static.DW1.Outputsurfaceindex = RENDERCOPY_DST_INDEX;
681 
682         if (m_currKernelId == KERNEL_CopyKernel_1D_to_2D_NV12)
683         {
684             WalkerNV12Static.DW2.Widthdword = (m_Source.dwWidth * iBytePerPixelPerPlane + 3) / 4;
685             WalkerNV12Static.DW3.Height = m_Source.dwHeight;
686             WalkerNV12Static.DW4.ShiftLeftOffsetInBytes = m_Source.dwOffset;
687             WalkerNV12Static.DW5.Widthstride = m_Source.dwPitch;
688             WalkerNV12Static.DW6.Heightstride = m_Source.dwHeight;
689         }
690         else
691         {
692             WalkerNV12Static.DW2.Widthdword = (m_Source.dwWidth < m_Target.dwWidth) ? m_Source.dwWidth : m_Target.dwWidth;
693             WalkerNV12Static.DW2.Widthdword = (WalkerNV12Static.DW2.Widthdword * iBytePerPixelPerPlane + 3) / 4;
694             WalkerNV12Static.DW3.Height = (m_Source.dwHeight < m_Target.dwHeight) ? m_Source.dwHeight:m_Target.dwHeight;
695             WalkerNV12Static.DW4.ShiftLeftOffsetInBytes = m_Target.dwOffset;
696             WalkerNV12Static.DW5.Widthstride = m_Target.dwPitch;
697             WalkerNV12Static.DW6.Heightstride = m_Target.dwHeight;
698         }
699 
700         iCurbeLength = sizeof(DP_RENDERCOPY_NV12_STATIC_DATA);
701         MCPY_NORMALMESSAGE("Load Curbe data: DW0.Inputsurfaceindex = %d, DW1.Outputsurfaceindex = %d, DW2.WidthDWord= %d, DW3.Height= %d,"
702             "DW4.ShiftLeftOffsetInBytes= %d,DW5.Widthstride = %d, DW6.Heightstride = % d.",
703             WalkerNV12Static.DW0.Inputsurfaceindex,
704             WalkerNV12Static.DW1.Outputsurfaceindex,
705             WalkerNV12Static.DW2.Widthdword,
706             WalkerNV12Static.DW3.Height,
707             WalkerNV12Static.DW4.ShiftLeftOffsetInBytes,
708             WalkerNV12Static.DW5.Widthstride,
709             WalkerNV12Static.DW6.Heightstride);
710         *piCurbeOffset = pRenderHal->pfnLoadCurbeData(
711          pRenderHal,
712          pRenderData->pMediaState,
713          &WalkerNV12Static,
714          iCurbeLength);
715     }
716     else if (m_Target.Format == Format_RGBP)
717     {
718         // Set relevant static data
719         MOS_ZeroMemory(&WalkerPlanarStatic, sizeof(DP_RENDERCOPY_RGBP_STATIC_DATA));
720 
721         if (m_currKernelId == KERNEL_CopyKernel_2D_to_1D_Planar)
722         {
723             WalkerPlanarStatic.DW0.InputsurfaceRindex = RENDERCOPY_SRC_INDEX + 2;
724             WalkerPlanarStatic.DW1.InputsurfaceGindex = RENDERCOPY_SRC_INDEX;
725             WalkerPlanarStatic.DW2.InputsurfaceBindex = RENDERCOPY_SRC_INDEX + 1;
726         }
727         else
728         {
729             WalkerPlanarStatic.DW0.InputsurfaceRindex = RENDERCOPY_SRC_INDEX;
730             WalkerPlanarStatic.DW1.InputsurfaceGindex = RENDERCOPY_SRC_INDEX + 1;
731             WalkerPlanarStatic.DW2.InputsurfaceBindex = RENDERCOPY_SRC_INDEX + 2;
732         }
733 
734         if (m_currKernelId == KERNEL_CopyKernel_1D_to_2D_Planar)
735         {
736             WalkerPlanarStatic.DW3.OutputsurfaceRindex = RENDERCOPY_DST_INDEX + 2;
737             WalkerPlanarStatic.DW4.OutputsurfaceGindex = RENDERCOPY_DST_INDEX;
738             WalkerPlanarStatic.DW5.OutputsurfaceBindex = RENDERCOPY_DST_INDEX + 1;
739         }
740         else
741         {
742             WalkerPlanarStatic.DW3.OutputsurfaceRindex = RENDERCOPY_DST_INDEX;
743             WalkerPlanarStatic.DW4.OutputsurfaceGindex = RENDERCOPY_DST_INDEX + 1;
744             WalkerPlanarStatic.DW5.OutputsurfaceBindex = RENDERCOPY_DST_INDEX + 2;
745         }
746 
747         if (m_currKernelId == KERNEL_CopyKernel_1D_to_2D_Planar)
748         {
749             WalkerPlanarStatic.DW6.Widthdword = m_Source.dwPitch / 4;
750             WalkerPlanarStatic.DW7.Height = m_Source.dwHeight;
751             WalkerPlanarStatic.DW8.ShiftLeftOffsetInBytes = m_Source.dwOffset;
752         }
753         else
754         {
755             WalkerPlanarStatic.DW6.Widthdword = m_Target.dwPitch / 4;
756             WalkerPlanarStatic.DW7.Height = m_Target.dwHeight;
757             WalkerPlanarStatic.DW8.ShiftLeftOffsetInBytes = m_Target.dwOffset;
758         }
759 
760         WalkerPlanarStatic.DW9.WidthdwordNoPadding = (m_Source.dwWidth < m_Target.dwWidth) ? m_Source.dwWidth : m_Target.dwWidth;
761         WalkerPlanarStatic.DW9.WidthdwordNoPadding = (WalkerPlanarStatic.DW9.WidthdwordNoPadding * iBytePerPixelPerPlane + 3) / 4;
762         WalkerPlanarStatic.DW10.Dst2DStartX = 0;
763         WalkerPlanarStatic.DW11.Dst2DStartY = 0;
764 
765         iCurbeLength = sizeof(DP_RENDERCOPY_RGBP_STATIC_DATA);
766         MCPY_NORMALMESSAGE("Load Curbe data: DW0.InputsurfaceRindex = %d, DW1.InputsurfaceGindex = %d, DW2.InputsurfaceBindex= %d, DW3.Height= %d,"
767             "DW4.OutputsurfaceGindex = %d, DW5.OutputsurfaceBindex = %d, DW6.Widthdword = %d, DW7.Height = %d, DW8.ShiftLeftOffsetInByte= %d,"
768             "DW9.WidthdwordNoPadding = %d, WalkerPlanarStatic.DW10.Dst2DStartX = %d, WalkerPlanarStatic.DW11.Dst2DStartY = %d.",
769             WalkerPlanarStatic.DW0.InputsurfaceRindex,
770             WalkerPlanarStatic.DW1.InputsurfaceGindex,
771             WalkerPlanarStatic.DW2.InputsurfaceBindex,
772             WalkerPlanarStatic.DW3.OutputsurfaceRindex,
773             WalkerPlanarStatic.DW4.OutputsurfaceGindex,
774             WalkerPlanarStatic.DW5.OutputsurfaceBindex,
775             WalkerPlanarStatic.DW6.Widthdword,
776             WalkerPlanarStatic.DW7.Height,
777             WalkerPlanarStatic.DW8.ShiftLeftOffsetInBytes,
778             WalkerPlanarStatic.DW9.WidthdwordNoPadding,
779             WalkerPlanarStatic.DW10.Dst2DStartX,
780             WalkerPlanarStatic.DW11.Dst2DStartY);
781 
782         *piCurbeOffset = pRenderHal->pfnLoadCurbeData(
783                                          pRenderHal,
784                                          pRenderData->pMediaState,
785                                          &WalkerPlanarStatic,
786                                          iCurbeLength);
787     }
788     else if ((m_Target.Format == Format_YUY2) || (m_Target.Format == Format_Y210) || (m_Target.Format == Format_Y216)
789               || (m_Target.Format == Format_AYUV) || (m_Target.Format == Format_Y410) || (m_Target.Format == Format_Y416)
790               || (m_Target.Format == Format_A8R8G8B8))
791     {
792         // Set relevant static data
793         MOS_ZeroMemory(&WalkerSinglePlaneStatic, sizeof(WalkerSinglePlaneStatic));
794 
795         WalkerSinglePlaneStatic.DW0.InputSurfaceIndex = RENDERCOPY_SRC_INDEX;
796         WalkerSinglePlaneStatic.DW1.OutputSurfaceIndex = RENDERCOPY_DST_INDEX;
797         if (m_currKernelId == KERNEL_CopyKernel_1D_to_2D_Packed)
798         {
799             WalkerSinglePlaneStatic.DW2.WidthDWord = m_Source.dwPitch / 4;
800             WalkerSinglePlaneStatic.DW3.Height = m_Source.dwHeight;
801             WalkerSinglePlaneStatic.DW4.ShiftLeftOffsetInBytes = m_Source.dwOffset;
802         }
803         else
804         {
805             WalkerSinglePlaneStatic.DW2.WidthDWord = m_Target.dwPitch / 4;
806             WalkerSinglePlaneStatic.DW3.Height = m_Target.dwHeight;
807             WalkerSinglePlaneStatic.DW4.ShiftLeftOffsetInBytes = m_Target.dwOffset;
808         }
809 
810         if ((m_currKernelId == KERNEL_CopyKernel_1D_to_2D_Packed) || (m_currKernelId == KERNEL_CopyKernel_2D_to_1D_Packed))
811         {
812             WalkerSinglePlaneStatic.DW5.ThreadHeight = (m_Source.dwHeight < m_Target.dwHeight) ? m_Source.dwHeight : m_Target.dwHeight;
813             WalkerSinglePlaneStatic.DW5.ThreadHeight = (WalkerSinglePlaneStatic.DW5.ThreadHeight + 32 - 1) / 32;
814         }
815         else if (m_currKernelId == KERNEL_CopyKernel_2D_to_2D_Packed)
816         {
817             WalkerSinglePlaneStatic.DW5.ThreadHeight = (m_Source.dwHeight + 8 - 1) / 8;
818         }
819         else
820         {
821             MCPY_ASSERTMESSAGE("LoadStaticData wrong kernel file.");
822             return MOS_STATUS_INVALID_PARAMETER;
823         }
824 
825         WalkerSinglePlaneStatic.DW6.WidthdwordNoPadding = (m_Source.dwWidth < m_Target.dwWidth) ? m_Source.dwWidth : m_Target.dwWidth;
826         WalkerSinglePlaneStatic.DW6.WidthdwordNoPadding = (WalkerSinglePlaneStatic.DW6.WidthdwordNoPadding * iBytePerPixelPerPlane + 3) / 4;
827         WalkerSinglePlaneStatic.DW7.Dst2DStartX = 0;
828         WalkerSinglePlaneStatic.DW8.Dst2DStartY = 0;
829 
830         iCurbeLength = sizeof(DP_RENDERCOPY_PACKED_STATIC_DATA);
831         MCPY_NORMALMESSAGE("Load Curbe data: DW0.InputSurfaceIndex = %d, DW1.OutputSurfaceIndex = %d, DW2.WidthDWord= %d, DW3.Height= %d,"
832             "DW4.ShiftLeftOffsetInBytes= %d,DW5.ThreadHeight = %d, DW6.WidthdwordNoPadding = %d, DW7.Dst2DStartX = %d, DW8.Dst2DStartY = %d.",
833             WalkerSinglePlaneStatic.DW0.InputSurfaceIndex,
834             WalkerSinglePlaneStatic.DW1.OutputSurfaceIndex,
835             WalkerSinglePlaneStatic.DW2.WidthDWord,
836             WalkerSinglePlaneStatic.DW3.Height,
837             WalkerSinglePlaneStatic.DW4.ShiftLeftOffsetInBytes,
838             WalkerSinglePlaneStatic.DW5.ThreadHeight,
839             WalkerSinglePlaneStatic.DW6.WidthdwordNoPadding,
840             WalkerSinglePlaneStatic.DW7.Dst2DStartX,
841             WalkerSinglePlaneStatic.DW8.Dst2DStartY);
842 
843         *piCurbeOffset = pRenderHal->pfnLoadCurbeData(
844          pRenderHal,
845          pRenderData->pMediaState,
846          &WalkerSinglePlaneStatic,
847          iCurbeLength);
848     }
849     else
850     {
851          MCPY_ASSERTMESSAGE("can't support Target format %d", m_Target.Format);
852     }
853 
854     if (*piCurbeOffset < 0)
855     {
856         return MOS_STATUS_UNKNOWN;
857     }
858 
859     pRenderData->iCurbeLength = iCurbeLength;
860 
861     return eStatus;
862 }
863 
864  //!
865  //! \brief    Render copy omputer walker setup
866  //! \details  Computer walker setup for render copy
867  //! \param    PMHW_WALKER_PARAMS pWalkerParams
868  //!           [in/out] Pointer to Walker params
869  //! \return   MOS_STATUS
870  //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
871  //!
RenderCopyComputerWalker(PMHW_GPGPU_WALKER_PARAMS pWalkerParams)872  MOS_STATUS RenderCopyStateNext::RenderCopyComputerWalker(
873  PMHW_GPGPU_WALKER_PARAMS    pWalkerParams)
874 {
875     MOS_STATUS                              eStatus = MOS_STATUS_SUCCESS;
876     PMEDIACOPY_RENDER_DATA                  pRenderData = &m_RenderData;
877     RECT                                    AlignedRect;
878     int32_t                                 iBytePerPixelPerPlane = GetBytesPerPixelPerPlane(m_Target.Format);
879 
880     MCPY_CHK_NULL_RETURN(pRenderData);
881 
882     if ((iBytePerPixelPerPlane < 1) || (iBytePerPixelPerPlane > 8))
883     {
884         MCPY_ASSERTMESSAGE("RenderCopyComputerWalker wrong pixel size.");
885         return MOS_STATUS_INVALID_PARAMETER;
886     }
887 
888     if ((m_Target.Format == Format_YUY2) || (m_Target.Format == Format_Y210) || (m_Target.Format == Format_Y216)
889         || (m_Target.Format == Format_AYUV) || (m_Target.Format == Format_Y410) || (m_Target.Format == Format_Y416)
890         || (m_Target.Format == Format_A8R8G8B8))
891     {
892         if ((m_currKernelId == KERNEL_CopyKernel_1D_to_2D_Packed) || (m_currKernelId == KERNEL_CopyKernel_2D_to_1D_Packed))
893         {
894             m_WalkerHeightBlockSize = 32;
895         }
896         else if (m_currKernelId == KERNEL_CopyKernel_2D_to_2D_Packed)
897         {
898             m_WalkerHeightBlockSize = 8;
899         }
900         else
901         {
902             MCPY_ASSERTMESSAGE("RenderCopyComputerWalker wrong kernel file.");
903             return MOS_STATUS_INVALID_PARAMETER;
904         }
905     }
906     else
907     {
908         m_WalkerHeightBlockSize = 8;
909     }
910 
911     if ((m_currKernelId == KERNEL_CopyKernel_2D_to_1D_Packed) ||
912         (m_currKernelId == KERNEL_CopyKernel_2D_to_1D_NV12) ||
913         (m_currKernelId == KERNEL_CopyKernel_2D_to_1D_Planar))
914     {
915         m_WalkerWidthBlockSize = 16;
916     }
917     else
918     {
919         m_WalkerWidthBlockSize = 128;
920     }
921 
922     // Set walker cmd params - Rasterscan
923     MOS_ZeroMemory(pWalkerParams, sizeof(*pWalkerParams));
924 
925 
926     AlignedRect.left   = 0;
927     AlignedRect.top    = 0;
928     AlignedRect.right  = (m_Source.dwPitch < m_Target.dwPitch) ? m_Source.dwPitch : m_Target.dwPitch;
929     AlignedRect.bottom = (m_Source.dwHeight < m_Target.dwHeight) ? m_Source.dwHeight : m_Target.dwHeight;
930     // Calculate aligned output area in order to determine the total # blocks
931    // to process in case of non-16x16 aligned target.
932     AlignedRect.right += m_WalkerWidthBlockSize - 1;
933     AlignedRect.bottom += m_WalkerHeightBlockSize - 1;
934     AlignedRect.left -= AlignedRect.left % m_WalkerWidthBlockSize;
935     AlignedRect.top -= AlignedRect.top % m_WalkerHeightBlockSize;
936     AlignedRect.right -= AlignedRect.right % m_WalkerWidthBlockSize;
937     AlignedRect.bottom -= AlignedRect.bottom % m_WalkerHeightBlockSize;
938 
939     pWalkerParams->InterfaceDescriptorOffset = pRenderData->iMediaID;
940 
941     pWalkerParams->GroupStartingX = (AlignedRect.left / m_WalkerWidthBlockSize);
942     pWalkerParams->GroupStartingY = (AlignedRect.top / m_WalkerHeightBlockSize);
943 
944     // Set number of blocks
945     pRenderData->iBlocksX =
946         ((AlignedRect.right - AlignedRect.left) + m_WalkerWidthBlockSize - 1) / m_WalkerWidthBlockSize;
947     pRenderData->iBlocksY =
948         ((AlignedRect.bottom - AlignedRect.top) + m_WalkerHeightBlockSize -1)/ m_WalkerHeightBlockSize;
949 
950     // Set number of blocks, block size is m_WalkerWidthBlockSize x m_WalkerHeightBlockSize.
951     pWalkerParams->GroupWidth = pRenderData->iBlocksX;
952     pWalkerParams->GroupHeight = pRenderData->iBlocksY; // hight/m_WalkerWidthBlockSize
953 
954     pWalkerParams->ThreadWidth = 1;
955     pWalkerParams->ThreadHeight = 1;
956     pWalkerParams->ThreadDepth = 1;
957     pWalkerParams->IndirectDataStartAddress = pRenderData->iCurbeOffset;
958     // Indirect Data Length is a multiple of 64 bytes (size of L3 cacheline). Bits [5:0] are zero.
959     pWalkerParams->IndirectDataLength = MOS_ALIGN_CEIL(pRenderData->iCurbeLength, 1 << MHW_COMPUTE_INDIRECT_SHIFT);
960     pWalkerParams->BindingTableID = pRenderData->iBindingTable;
961     MCPY_NORMALMESSAGE("WidthBlockSize %d, HeightBlockSize %d, Widththreads %d, Heightthreads%d",
962         m_WalkerWidthBlockSize, m_WalkerHeightBlockSize, pWalkerParams->GroupWidth, pWalkerParams->GroupHeight);
963 
964     return eStatus;
965 }
966 
CopySurface(PMOS_RESOURCE src,PMOS_RESOURCE dst)967  MOS_STATUS RenderCopyStateNext::CopySurface(
968      PMOS_RESOURCE src,
969      PMOS_RESOURCE dst)
970  {
971      MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
972      m_Source.OsResource = *src;
973      m_Source.Format = Format_Invalid;
974      m_osInterface->pfnGetResourceInfo(m_osInterface, src, &m_Source);
975 
976      m_Target.OsResource = *dst;
977      m_Target.Format = Format_Invalid;
978      m_osInterface->pfnGetResourceInfo(m_osInterface, dst, &m_Target);
979 
980      if ((m_Target.Format != Format_RGBP) && (m_Target.Format != Format_NV12) && (m_Target.Format != Format_RGB)
981          && (m_Target.Format != Format_P010) && (m_Target.Format != Format_P016) && (m_Target.Format != Format_YUY2)
982          && (m_Target.Format != Format_Y210) && (m_Target.Format != Format_Y216) && (m_Target.Format != Format_AYUV)
983          && (m_Target.Format != Format_Y410) && (m_Target.Format != Format_Y416) && (m_Target.Format != Format_A8R8G8B8))
984      {
985          MCPY_ASSERTMESSAGE("Can't suppport format %d ", m_Target.Format);
986          return MOS_STATUS_INVALID_PARAMETER;
987      }
988 
989      MCPY_CHK_STATUS_RETURN(GetCurentKernelID());
990      return SubmitCMD();
991  }