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 }