1 /*
2 * Copyright (c) 2007-2017, 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 cm_wrapper_os.cpp
24 //! \brief Contains implementations of Linux-dependent functions for executing
25 //! commands from cmrtlib.
26 //!
27
28 #include "cm_wrapper.h"
29
30 #include "cm_device_rt.h"
31 #include "cm_surface_2d_rt.h"
32 #include "media_libva_util.h"
33 #include "cm_extension_creator.h"
34 #include "mos_os_specific.h"
35
36 extern MOS_FORMAT Mos_Specific_FmtOsToMos(
37 MOS_OS_FORMAT format);
38
39 extern MOS_OS_FORMAT Mos_Specific_FmtMosToOs(
40 MOS_FORMAT format);
41
42 using CMRT_UMD::CmDeviceRT;
43 //!
44 //! \brief Create Cm Device from VA Driver Context.
45 //! \details Create a CmCtx and a associated MOS_CONTEXT. Put the CmCtx into
46 //! the heap of VA Context.
47 //! \param vaDriverCtx
48 //! [in] pointer to va drv conetext.
49 //! \param device
50 //! [in,out] reference to cm device pointer.
51 //! \param devOption
52 //! [in] cm device creation option.
53 //! \return int32_t
54 //! CM_SUCCESS if success, else fail reason.
55 //!
CreateCmDeviceFromVA(VADriverContextP vaDriverCtx,CmDevice * & device,uint32_t devOption)56 int32_t CreateCmDeviceFromVA(VADriverContextP vaDriverCtx,
57 CmDevice* &device,
58 uint32_t devOption)
59 {
60 int32_t hRes = CM_SUCCESS;
61 PDDI_MEDIA_CONTEXT mediaCtx;
62 PCM_CONTEXT cmCtx;
63 uint32_t ctxIndex;
64 PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT vaCtxHeapElement;
65 VAContextID vaContextID;
66
67 mediaCtx = DdiMedia_GetMediaContext(vaDriverCtx);
68
69 // allocate cmCtx
70 cmCtx = (PCM_CONTEXT)MOS_AllocAndZeroMemory(sizeof(CM_CONTEXT));
71 CM_CHK_NULL_RETURN_WITH_MSG(cmCtx, CM_INVALID_UMD_CONTEXT, "Null cmCtx!");
72
73 // init cmCtx
74 cmCtx->mosCtx.bufmgr = mediaCtx->pDrmBufMgr;
75 cmCtx->mosCtx.m_gpuContextMgr = mediaCtx->m_gpuContextMgr;
76 cmCtx->mosCtx.m_cmdBufMgr = mediaCtx->m_cmdBufMgr;
77 cmCtx->mosCtx.fd = mediaCtx->fd;
78 cmCtx->mosCtx.wRevision = 0;
79 cmCtx->mosCtx.iDeviceId = mediaCtx->iDeviceId;
80 cmCtx->mosCtx.SkuTable = mediaCtx->SkuTable;
81 cmCtx->mosCtx.WaTable = mediaCtx->WaTable;
82 cmCtx->mosCtx.gtSystemInfo = *(mediaCtx->pGtSystemInfo);
83 cmCtx->mosCtx.platform = mediaCtx->platform;
84 cmCtx->mosCtx.pGmmClientContext = mediaCtx->pGmmClientContext;
85 cmCtx->mosCtx.m_osDeviceContext = mediaCtx->m_osDeviceContext;
86 cmCtx->mosCtx.m_apoMosEnabled = mediaCtx->m_apoMosEnabled;
87 cmCtx->mosCtx.m_auxTableMgr = mediaCtx->m_auxTableMgr;
88 cmCtx->mosCtx.pPerfData = (PERF_DATA *)MOS_AllocAndZeroMemory(sizeof(PERF_DATA));
89
90 if (cmCtx->mosCtx.pPerfData == nullptr)
91 {
92 MOS_FreeMemAndSetNull(cmCtx); // free cm ctx
93 CM_ASSERTMESSAGE("Failed to allocate perfData in mos context \n");
94 return CM_OUT_OF_HOST_MEMORY;
95 }
96
97 // Create Cm Device
98 hRes = CreateCmDevice(&(cmCtx->mosCtx), device, devOption);
99 if(hRes != CM_SUCCESS)
100 {
101 MOS_FreeMemAndSetNull(cmCtx); // free cm ctx
102 CM_ASSERTMESSAGE("Failed to call CmDevice::Create Error %d \n",hRes);
103 return hRes;
104 }
105 CmDeviceRT* deviceRT = static_cast<CmDeviceRT*>(device);
106 DdiMediaUtil_LockMutex(&mediaCtx->CmMutex);
107
108 // get Free Cm context index
109 vaCtxHeapElement = DdiMediaUtil_AllocPVAContextFromHeap(mediaCtx->pCmCtxHeap);
110 if (nullptr == vaCtxHeapElement)
111 {
112 CmDeviceRT::Destroy(deviceRT); // destroy cm device
113 device = nullptr;
114 MOS_FreeMemAndSetNull(cmCtx); // free cm ctx
115 DdiMediaUtil_UnLockMutex(&mediaCtx->CmMutex);
116 CM_ASSERTMESSAGE("CM Context number exceeds maximum.");
117 return VA_STATUS_ERROR_INVALID_CONTEXT;
118 }
119
120 // store cmCtx in pMedia
121 vaCtxHeapElement->pVaContext = (void *)cmCtx;
122 vaContextID = (VAContextID)(vaCtxHeapElement->uiVaContextID + DDI_MEDIA_VACONTEXTID_OFFSET_CM);
123
124 //Set VaCtx ID to Cm device
125 deviceRT->SetVaCtxID(vaContextID);
126
127 // increate CM context number
128 mediaCtx->uiNumCMs++;
129
130 DdiMediaUtil_UnLockMutex(&mediaCtx->CmMutex);
131
132 return hRes;
133 }
134
135 //!
136 //! \brief Destroy Cm Device and free heap in VA context.
137 //! \param vaDriverCtx
138 //! [in] pointer to va drv conetext.
139 //! \param device
140 //! [in] pointer to cm device to release.
141 //! \return int32_t
142 //! CM_SUCCESS if success, else fail reason.
143 //!
DestroyCmDeviceFromVA(VADriverContextP vaDriverCtx,CmDevice * device)144 int32_t DestroyCmDeviceFromVA(VADriverContextP vaDriverCtx, CmDevice *device)
145 {
146 int32_t hr = CM_SUCCESS;
147 uint32_t index;
148 PDDI_MEDIA_CONTEXT mediaCtx;
149 PCM_CONTEXT cmCtx;
150 VAContextID vaContextID;
151 uint32_t ctxType;
152 VAStatus vaStatus;
153
154 if (nullptr == vaDriverCtx)
155 {
156 CM_ASSERTMESSAGE("Pointer to VADriverContext is invalid.");
157 return CM_NULL_POINTER;
158 }
159 CmDeviceRT* deviceRT = static_cast<CmDeviceRT*>(device);
160 if (nullptr == deviceRT)
161 {
162 return CM_SUCCESS;
163 }
164 //Get VaCtx ID in MediaCtx
165 deviceRT->GetVaCtxID(vaContextID);
166
167 // Get Cm context index
168 index = vaContextID & DDI_MEDIA_MASK_VACONTEXTID;
169
170 //Get Cm Context
171 cmCtx = (PCM_CONTEXT)DdiMedia_GetContextFromContextID(vaDriverCtx, vaContextID, &ctxType);
172 CM_CHK_NULL_RETURN_WITH_MSG(cmCtx, VA_STATUS_ERROR_INVALID_CONTEXT, "Null cmCtx.");
173
174 CM_CHK_CMSTATUS_GOTOFINISH(DestroyCmDevice(device));
175
176 // remove from context array
177 mediaCtx = DdiMedia_GetMediaContext(vaDriverCtx);
178 DdiMediaUtil_LockMutex(&mediaCtx->CmMutex);
179
180 MOS_FreeMemAndSetNull(cmCtx->mosCtx.pPerfData);
181
182 // destroy Cm context
183 MOS_FreeMemAndSetNull(cmCtx);
184
185 DdiMediaUtil_ReleasePVAContextFromHeap(mediaCtx->pCmCtxHeap, index);
186
187 mediaCtx->uiNumCMs--;
188
189 DdiMediaUtil_UnLockMutex(&mediaCtx->CmMutex);
190
191 finish:
192 return hr;
193 }
194
195 extern MOS_FORMAT VpGetFormatFromMediaFormat(DDI_MEDIA_FORMAT mf);
196 //*-----------------------------------------------------------------------------
197 //| Purpose: Get resource information from LibVA-created surface and fill into OsResource
198 // vaSurfaceID is the index to VA's surface
199 //| Returns: Result of the operation.
200 //*-----------------------------------------------------------------------------
CmFillMosResource(VASurfaceID vaSurfaceID,VADriverContext * vaDriverCtx,PMOS_RESOURCE osResource)201 int32_t CmFillMosResource( VASurfaceID vaSurfaceID,
202 VADriverContext* vaDriverCtx,
203 PMOS_RESOURCE osResource)
204 {
205 PDDI_MEDIA_CONTEXT mediaCtx;
206 DDI_MEDIA_SURFACE *surface;
207 CmDevice *device;
208
209 CM_CHK_NULL_RETURN_WITH_MSG(vaDriverCtx, CM_INVALID_UMD_CONTEXT, "Null umdCtx");
210
211 mediaCtx = DdiMedia_GetMediaContext(vaDriverCtx);
212 CM_CHK_NULL_RETURN_WITH_MSG(mediaCtx, CM_INVALID_UMD_CONTEXT, "Null mediaCtx");
213
214 CM_CHK_NULL_RETURN_WITH_MSG(mediaCtx->pSurfaceHeap, CM_INVALID_UMD_CONTEXT, "Null mediaCtx->pSurfaceHeap");
215 CM_CHK_COND_RETURN(((uint32_t)vaSurfaceID >= mediaCtx->pSurfaceHeap->uiAllocatedHeapElements), CM_INVALID_LIBVA_SURFACE, "Invalid surface");
216 surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, vaSurfaceID);
217 CM_CHK_NULL_RETURN_WITH_MSG(surface, CM_INVALID_LIBVA_SURFACE, "Null surface");
218 CM_ASSERT(surface->iPitch == GFX_ULONG_CAST(surface->pGmmResourceInfo->GetRenderPitch()));
219 CM_CHK_NULL_RETURN_WITH_MSG(surface->bo, CM_INVALID_LIBVA_SURFACE, "Null BO");
220 CM_CHK_NULL_RETURN_WITH_MSG(surface->pGmmResourceInfo, CM_INVALID_LIBVA_SURFACE, "Null GMMResInfo");
221
222 // Resets the Resource
223 Mos_ResetResource(osResource);
224
225 osResource->iWidth = surface->iWidth;
226 osResource->iHeight = surface->iHeight;
227 osResource->iDepth = 1;
228 osResource->iPitch = surface->iPitch;
229
230 osResource->iCount = 0;
231 osResource->bufname = (char *)"Libva2DSurface";
232
233 osResource->Format = VpGetFormatFromMediaFormat(surface->format);
234 osResource->bo = surface->bo;
235
236 osResource->TileType = LinuxToMosTileType(surface->TileType);
237 osResource->isTiled = surface->isTiled;
238
239 osResource->bMapped = surface->bMapped;
240 osResource->pData = (uint8_t*) surface->bo->virt;
241
242 osResource->pGmmResInfo = surface->pGmmResourceInfo;
243
244 // for wrapper to new MOS MODS interface
245 osResource->bConvertedFromDDIResource = true;
246
247 return CM_SUCCESS;
248 }
249
CmOSFmtToMosFmt(CM_OSAL_SURFACE_FORMAT format)250 MOS_FORMAT CmOSFmtToMosFmt(CM_OSAL_SURFACE_FORMAT format)
251 {
252 //CM_SURFACE_FORMAT_R8U/R16U are not valid va surface format.
253 //These two formats are MDF specific, so we add the mapping here.
254 switch(format)
255 {
256 case CM_SURFACE_FORMAT_R8U: return Format_R8U;
257 case CM_SURFACE_FORMAT_R16U: return Format_R16U;
258 default:
259 return Mos_Specific_FmtOsToMos(format);
260 }
261 }
262
CmMosFmtToOSFmt(MOS_FORMAT format)263 CM_OSAL_SURFACE_FORMAT CmMosFmtToOSFmt(MOS_FORMAT format)
264 {
265 //CM_SURFACE_FORMAT_R8U/R16U are not valid va surface format.
266 //These two formats are MDF specific, so we add the mapping here.
267 switch(format)
268 {
269 case Format_R8U: return CM_SURFACE_FORMAT_R8U;
270 case Format_R16U: return CM_SURFACE_FORMAT_R16U;
271 default:
272 return Mos_Specific_FmtMosToOs(format);
273 }
274 }
275
ConvertToOperatingSystemAbstractionLayerFormat(void * src,uint32_t numOfFormats)276 int32_t ConvertToOperatingSystemAbstractionLayerFormat(void *src, uint32_t numOfFormats)
277 {
278 uint32_t i = 0 ;
279 if (src == nullptr || numOfFormats == 0)
280 {
281 CM_ASSERTMESSAGE("Error: Invalid input arguments.");
282 return CM_INVALID_ARG_VALUE;
283 }
284
285 for (i = 0; i < numOfFormats; ++i)
286 {
287 *((CM_OSAL_SURFACE_FORMAT*)src + i) = CmMosFmtToOSFmt(*((CM_SURFACE_FORMAT*)src + i));
288 }
289 return CM_SUCCESS;
290 }
291
292 struct CM_CREATESURFACE2DUP_PARAM
293 {
294 uint32_t width; // [in] width of 2D texture in pixel
295 uint32_t height; // [in] height of 2D texture in pixel
296 CM_OSAL_SURFACE_FORMAT format; // [in] 2D texture foramt in OS layer.
297 void *sysMem; // [in] Pointer to system memory
298 void *surface2DUPHandle; // [out] pointer of CmSurface2D used in driver
299 int32_t returnValue; // [out] the return value from driver
300 };
301 typedef CM_CREATESURFACE2DUP_PARAM *PCM_CREATESURFACE2DUP_PARAM;
302
303 struct CM_GETSURFACE2DINFO_PARAM
304 {
305 uint32_t width; // [in] Surface Width
306 uint32_t height; // [in] Surface Height
307 CM_OSAL_SURFACE_FORMAT format; // [in] Surface Format
308 uint32_t pitch; // [out] Pitch
309 uint32_t physicalSize; // [out] Physical size
310 uint32_t returnValue; // [out] Return value
311 };
312 typedef CM_GETSURFACE2DINFO_PARAM *PCM_GETSURFACE2DINFO_PARAM;
313
314 struct CM_CREATE_SURFACE3D_PARAM
315 {
316 uint32_t width; // [in] width of 3D in pixel
317 uint32_t height; // [in] height of 3D in pixel
318 uint32_t depth; // [in] depth of 3D surface in pixel
319 CM_OSAL_SURFACE_FORMAT format; // [in] 2D texture foramt in OS abstraction layer.
320 void *surface3DHandle; // [out] pointer of CmSurface3D used in driver
321 int32_t returnValue; // [out] the return value from driver
322 };
323 typedef CM_CREATE_SURFACE3D_PARAM *PCM_CREATE_SURFACE3D_PARAM;
324
325 using CMRT_UMD::CmSurface2DRT;
326 using CMRT_UMD::CmWrapperEx;
327 using CMRT_UMD::CmSurface2DUP;
328 using CMRT_UMD::CmSurface3D;
329 //*-----------------------------------------------------------------------------
330 //| Purpose: CMRT thin layer library supported function execution
331 //| Return: CM_SUCCESS if successful
332 //*-----------------------------------------------------------------------------
CmThinExecute(VADriverContextP vaDriverCtx,void * deviceHandle,uint32_t inputFunctionId,void * inputData,uint32_t inputDataLen)333 int32_t CmThinExecute(VADriverContextP vaDriverCtx,
334 void *deviceHandle,
335 uint32_t inputFunctionId,
336 void *inputData,
337 uint32_t inputDataLen)
338 {
339 CmDevice *device = nullptr;
340 CmDeviceRT *deviceRT = nullptr;
341 VADriverContextP hUMDevice = nullptr;
342 void *cmPrivateInputData = nullptr;
343 uint32_t cmPrivateInputDataSize = 0 ;
344 CMRT_UMD::CmSurface2D *pCmSurface2d = nullptr;
345 SurfaceIndex *surfaceIndex = nullptr;
346 CM_FUNCTION_ID cmFunctionID;
347 int32_t hr = CM_SUCCESS;
348 int32_t cmRet = CM_INVALID_PRIVATE_DATA;
349
350 hUMDevice = vaDriverCtx;
351 cmPrivateInputData = inputData;
352 cmPrivateInputDataSize = inputDataLen;
353 cmFunctionID = (CM_FUNCTION_ID)inputFunctionId;
354 device = (CmDevice *)deviceHandle;
355 deviceRT = static_cast<CmDeviceRT*>(device);
356
357 switch(cmFunctionID)
358 {
359 case CM_FN_CREATECMDEVICE:
360 PCM_CREATECMDEVICE_PARAM cmDeviceParam;
361 cmDeviceParam = (PCM_CREATECMDEVICE_PARAM)(cmPrivateInputData);
362 //Create Cm Device
363 cmRet = CreateCmDeviceFromVA(vaDriverCtx, device, cmDeviceParam->devCreateOption);
364 if ( cmRet == CM_SUCCESS)
365 {
366 CM_CHK_NULL_RETURN_WITH_MSG(device, VA_STATUS_ERROR_INVALID_CONTEXT, "Null device.");
367 deviceRT = static_cast<CmDeviceRT*>(device);
368 deviceRT->RegisterCallBack(cmDeviceParam->callbackReleaseVaSurf);
369 cmDeviceParam->driverStoreEnabled = deviceRT->GetDriverStoreFlag();
370 }
371 //Fill the output message
372 cmDeviceParam->deviceHandle = device;
373 cmDeviceParam->returnValue = cmRet;
374 cmDeviceParam->version = CM_VERSION;
375 break;
376
377 case CM_FN_DESTROYCMDEVICE:
378 PCM_DESTROYCMDEVICE_PARAM cmDevDestroyParam;
379 cmDevDestroyParam = (PCM_DESTROYCMDEVICE_PARAM)(cmPrivateInputData);
380 device = (CmDevice *)(cmDevDestroyParam->deviceHandle);
381 cmRet = DestroyCmDeviceFromVA(vaDriverCtx,device);
382 //Fill the output message
383 cmDevDestroyParam->deviceHandle = nullptr;
384 cmDevDestroyParam->returnValue = cmRet;
385 break;
386
387 case CM_FN_CMDEVICE_CREATESURFACE2D:
388 PCM_CREATESURFACE2D_PARAM cmCreate2DParam;
389 MOS_RESOURCE mosResource ;
390 MOS_ZeroMemory(&mosResource, sizeof(MOS_RESOURCE));
391 cmCreate2DParam = (PCM_CREATESURFACE2D_PARAM)(cmPrivateInputData);
392 if ( cmCreate2DParam->isLibvaCreated )
393 {
394 //LibVA-created Surface2D
395 cmRet = CmFillMosResource(cmCreate2DParam->vaSurfaceID,
396 vaDriverCtx,
397 &mosResource);
398
399 if( cmRet != CM_SUCCESS)
400 {
401 CM_ASSERTMESSAGE("Error: Failed to fill MOS resource.");
402 cmCreate2DParam->returnValue = cmRet;
403 return cmRet;
404 }
405
406 cmRet = deviceRT->CreateSurface2D(&mosResource, cmCreate2DParam->isCmCreated, pCmSurface2d);
407 if( cmRet != CM_SUCCESS)
408 {
409 CM_ASSERTMESSAGE("Error: Failed to create surface 2D from MOS resource.");
410 cmCreate2DParam->returnValue = cmRet;
411 return cmRet;
412 }
413
414 CmSurface2DRT *surface2dRT = static_cast<CmSurface2DRT *>(pCmSurface2d);
415 surface2dRT->SetVaSurfaceID(cmCreate2DParam->vaSurfaceID, cmCreate2DParam->vaDisplay);
416 }
417 else
418 {
419 // CM Created Surface2D
420 cmRet = device->CreateSurface2D(
421 cmCreate2DParam->width,
422 cmCreate2DParam->height,
423 CmOSFmtToMosFmt(cmCreate2DParam->format),
424 pCmSurface2d);
425 }
426 //Create Surface Index
427 if( cmRet == CM_SUCCESS)
428 {
429 cmCreate2DParam->cmSurface2DHandle = pCmSurface2d;
430 }
431
432 //Fill output message
433 cmCreate2DParam->returnValue = cmRet;
434 break;
435
436 case CM_FN_CMDEVICE_CREATESURFACE2DUP:
437 CM_CREATESURFACE2DUP_PARAM *cmCreate2DUpParam;
438 CMRT_UMD::CmSurface2DUP *cmSurface2dup;
439 cmCreate2DUpParam = static_cast<CM_CREATESURFACE2DUP_PARAM*>(inputData);
440 cmRet = device->CreateSurface2DUP(cmCreate2DUpParam->width,
441 cmCreate2DUpParam->height,
442 CmOSFmtToMosFmt(cmCreate2DUpParam->format),
443 cmCreate2DUpParam->sysMem, cmSurface2dup);
444 if( cmRet == CM_SUCCESS)
445 {
446 cmCreate2DUpParam->surface2DUPHandle = static_cast<CmSurface2DUP*>(cmSurface2dup);
447 }
448 cmCreate2DUpParam->returnValue = cmRet;
449 break;
450
451 case CM_FN_CMDEVICE_CREATESURFACE3D:
452 CM_CREATE_SURFACE3D_PARAM *createSurf3dParam;
453 createSurf3dParam = static_cast<CM_CREATE_SURFACE3D_PARAM*>(inputData);
454 CMRT_UMD::CmSurface3D *cmSurface3d;
455 cmRet = device->CreateSurface3D(createSurf3dParam->width, createSurf3dParam->height,
456 createSurf3dParam->depth,
457 CmOSFmtToMosFmt(createSurf3dParam->format),
458 cmSurface3d);
459 if(cmRet == CM_SUCCESS)
460 {
461 createSurf3dParam->surface3DHandle = static_cast<CmSurface3D*>(cmSurface3d);
462 }
463 createSurf3dParam->returnValue = cmRet;
464 break;
465
466 case CM_FN_CMDEVICE_GETSURFACE2DINFO:
467 CM_GETSURFACE2DINFO_PARAM *cmGet2DinfoParam;
468 cmGet2DinfoParam = static_cast<CM_GETSURFACE2DINFO_PARAM*>(inputData);
469 uint32_t pitch, physicalsize;
470 cmRet = device->GetSurface2DInfo(cmGet2DinfoParam->width, cmGet2DinfoParam->height,
471 CmOSFmtToMosFmt(cmGet2DinfoParam->format),
472 pitch, physicalsize);
473 cmGet2DinfoParam->pitch = pitch;
474 cmGet2DinfoParam->physicalSize = physicalsize;
475 cmGet2DinfoParam->returnValue = cmRet;
476 break;
477
478 default:
479 hr = CmThinExecuteInternal(device, cmFunctionID, cmPrivateInputData, cmPrivateInputDataSize);
480 if (hr == CM_INVALID_PRIVATE_DATA)
481 {
482 CmWrapperEx *wrapperEx = CmExtensionCreator<CmWrapperEx>::CreateClass();
483 if (wrapperEx != nullptr)
484 {
485 wrapperEx->Initialize((void *)vaDriverCtx);
486 hr = wrapperEx->Execute(device,cmFunctionID, cmPrivateInputData, cmPrivateInputDataSize);
487 MOS_Delete(wrapperEx);
488 }
489 else
490 {
491 hr = CM_OUT_OF_HOST_MEMORY;
492 }
493 }
494 }
495
496 return hr;
497 }
498