/*
* Copyright (c) 2017, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "cm_device.h"
#include <cstdarg>
#include "cm_debug.h"
#include "cm_mem.h"
#if USE_EXTENSION_CODE
#include "cm_gtpin_external_interface.h"
#endif
#include "cm_printf_host.h"
#include "cm_surface_manager.h"
#include "cm_queue.h"
#include "cm_perf_statistics.h"
#include "cm_timer.h"

class CmBuffer;
class CmBufferUP;
class CmBufferSVM;

#if MDF_PROFILER_ENABLED
CmPerfStatistics gCmPerfStatistics;  // global instance to record API's perf
#endif

CM_RT_API int32_t CmDevice_RT::CreateBuffer(uint32_t size, CmBuffer* &buffer)
{
    INSERT_PROFILER_RECORD();

    return m_surfaceManager->CreateBuffer(size, buffer);
}

CM_RT_API int32_t CmDevice_RT::CreateBufferUP(uint32_t size, void* sysMem, CmBufferUP* &buffer)
{
    INSERT_PROFILER_RECORD();

    return m_surfaceManager->CreateBufferUP( size, sysMem, buffer);
}

CM_RT_API int32_t CmDevice_RT::DestroySurface(CmBuffer* &buffer)
{
    INSERT_PROFILER_RECORD();

    return m_surfaceManager->DestroyBuffer(buffer);
}

CM_RT_API int32_t CmDevice_RT::DestroyBufferUP(CmBufferUP* &buffer)
{
    INSERT_PROFILER_RECORD();

    return m_surfaceManager->DestroyBufferUP(buffer);
}

//!
//! Create a CmSurface2D
//! Input :
//!     Surface width, height and format;
//!     Reference to the pointer to the CmSurface2D .
//! Output:
//!     CM_SUCCESS if the CmSurface2D is successfully created;
//!     CM_OUT_OF_HOST_MEMORY if out of system memory;
//!     CM_SURFACE_ALLOCATION_FAILURE if surface creation fails;
//!     CM_FAILURE otherwise;
//!NOTES: general API
CM_RT_API int32_t CmDevice_RT::CreateSurface2D(uint32_t width, uint32_t height, CM_SURFACE_FORMAT format, CmSurface2D* & surface )
{
    INSERT_PROFILER_RECORD();

    return m_surfaceManager->CreateSurface2D( width,  height,  format, surface);;
}

CM_RT_API int32_t CmDevice_RT::CreateSurface2DUP( uint32_t width, uint32_t height, CM_SURFACE_FORMAT format, void* sysMem, CmSurface2DUP* &surface )
{
    INSERT_PROFILER_RECORD();

    return m_surfaceManager->CreateSurface2DUP( width, height, format, sysMem, surface);
}

CM_RT_API int32_t CmDevice_RT::DestroySurface2DUP( CmSurface2DUP* &surface)
{
    INSERT_PROFILER_RECORD();

    return m_surfaceManager->DestroySurface2DUP(surface);
}

CM_RT_API int32_t CmDevice_RT::DestroySurface( CmSurface2D* &surface2d)
{
    INSERT_PROFILER_RECORD();

    return m_surfaceManager->DestroySurface(surface2d);
}

CM_RT_API int32_t CmDevice_RT::GetSurface2DInfo( uint32_t width, uint32_t height, CM_SURFACE_FORMAT format, uint32_t & pitch, uint32_t & physicalSize)
{
    INSERT_PROFILER_RECORD();

    CM_GETSURFACE2DINFO_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_GETSURFACE2DINFO_PARAM ) );
    inParam.width = width;
    inParam.height = height;
    inParam.format = format;

    int32_t hr = OSALExtensionExecute(CM_FN_CMDEVICE_GETSURFACE2DINFO,
                                      &inParam, sizeof(inParam));
    CHK_FAILURE_RETURN(hr);
    CHK_FAILURE_RETURN(inParam.returnValue);

    pitch = inParam.pitch;
    physicalSize = inParam.physicalSize;
    return CM_SUCCESS;
}

//!
//! Load the code of one or more kernels in common ISA.
//! Jit-ting of the common ISA code can happen either in LoadProgram or CreateKernel.
//! Jit options set in LoadProgram are for all kernels within the code.
//! Jit options set in CreateKernel are for the specific kernel, overwriting the jit options set in program level. LoadProgram can be called multiple times for the same code.
//! Jit options is a null terminated string. string length ( excluding the null terminater )shoudl be
//! less than 512 (CM_MAX_OPTION_SIZE_IN_BYTE ). Otherwise the option is ignored.
//! Each time a now CmProgram object is generated.
//!
//! Input:
//!     1) Pointer pointing to the common ISA code
//!     2) code size in byte
//!     3) Reference to the pointer to the CmProgram.
//!     4) Jit options. This argument is optional.
//! Output:
//!     CM_SUCCESS if the CmProgram is successfully created;
//!     CM_INVALID_KERNELS if any kernel is invalid;
//!     CM_OUT_OF_HOST_MEMORY if out of system memory;
//!     CM_FAILURE otherwise;
//!

CM_RT_API int32_t CmDevice_RT::LoadProgram( void* commonISACode, const uint32_t size, CmProgram*& program,  const char* options )
{
    INSERT_PROFILER_RECORD();

    if( (commonISACode == nullptr) || (size == 0) )
    {
        CmAssert( 0 );
        return CM_INVALID_COMMON_ISA;
    }

    return CreateProgram(commonISACode, size, program, options);
}

int32_t CmDevice_RT::CreateProgram(void* commonISACode,
                                   const uint32_t size,
                                   CmProgram*& program,
                                   const char* options)
{
    CM_LOADPROGRAM_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_LOADPROGRAM_PARAM ) );
    inParam.cisaCode = commonISACode;
    inParam.cisaCodeSize = size;
    inParam.options = (char *)options;

    int32_t hr = OSALExtensionExecute(CM_FN_CMDEVICE_LOADPROGRAM,
                                      &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(hr);
    CHK_FAILURE_RETURN(inParam.returnValue);

    program = (CmProgram *)inParam.cmProgramHandle;

    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::DestroyProgram(CmProgram* & program )
{
    INSERT_PROFILER_RECORD();

    if( program == nullptr )
    {
        return CM_FAILURE;
    }

    CM_DESTROYPROGRAM_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_DESTROYPROGRAM_PARAM ) );
    inParam.cmProgramHandle = program;

    int32_t hr = OSALExtensionExecute(CM_FN_CMDEVICE_DESTROYPROGRAM,
                                      &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(hr);
    CHK_FAILURE_RETURN(inParam.returnValue);

    program = nullptr;

    return CM_SUCCESS;
}

//!
//! Create a CmKernel_RT. Each kernel can run in multiple threads.
//! If CreateKernel is called multiple times using the same CmProgram,
//! the same kernel name, and the same options, only in the first time a new CmKernel_RT is generated,
//! all following calls only return the existing CmKernel_RT.
//! Otherwise, each time a new CmKernel_RT is generated.
//! Input :
//!     1) CM Program from which the kernel is created
//!     2) CM kernel function (genx_main) name
//!     3) Reference to the pointer to the CmKernel_RT .
//!     4) Jit options for this kernel, overwriting the jit options in
//!        CmProgram level for this specific kernel. This argument is optional.
//! Output:
//!     CM_SUCCESS if the CmKernel_RT is successfully created;
//!     CM_OUT_OF_HOST_MEMORY if out of system memory;
//!     CM_FAILURE otherwise;
//!
CM_RT_API int32_t CmDevice_RT::CreateKernel( CmProgram* program, const char* kernelName, CmKernel* & kernel, const char* options )
{
    INSERT_PROFILER_RECORD();

    if(program == nullptr)
    {
        CmAssert( 0 );
        return CM_INVALID_ARG_VALUE;
    }

    CM_CREATEKERNEL_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_CREATEKERNEL_PARAM ) );
    inParam.cmProgramHandle = program;
    inParam.kernelName = (char*)kernelName;
    inParam.options = (char *)options;

    int32_t hr = OSALExtensionExecute(CM_FN_CMDEVICE_CREATEKERNEL,
                                      &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(hr);
    CHK_FAILURE_RETURN(inParam.returnValue);
    kernel = (CmKernel *)inParam.cmKernelHandle; // Got Object from CMRT@UMD directly.

    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::DestroyKernel( CmKernel*& kernel)
{
    INSERT_PROFILER_RECORD();

    CM_DESTROYKERNEL_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_DESTROYKERNEL_PARAM ) );
    inParam.cmKernelHandle = kernel;

    int32_t hr = OSALExtensionExecute(CM_FN_CMDEVICE_DESTROYKERNEL,
                                      &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(hr);
    CHK_FAILURE_RETURN(inParam.returnValue);
    kernel = nullptr;
    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::CreateTask(CmTask *& task)
{
    INSERT_PROFILER_RECORD();

    CM_CREATETASK_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_CREATETASK_PARAM ) );

    int32_t hr = OSALExtensionExecute(CM_FN_CMDEVICE_CREATETASK,
                                      &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(hr);
    CHK_FAILURE_RETURN(inParam.returnValue);
    task = (CmTask *)inParam.cmTaskHandle;

#if USE_EXTENSION_CODE
    GTPIN_MAKER_FUNCTION(CmrtCodeMarkerForGTPin_CreateTask(this, task));
#endif
    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::DestroyTask( CmTask*& task)
{
    INSERT_PROFILER_RECORD();

#if USE_EXTENSION_CODE
    GTPIN_MAKER_FUNCTION(CmrtCodeMarkerForGTPin_DestroyTask(this, task));
#endif

    CM_DESTROYTASK_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_DESTROYTASK_PARAM ) );
    inParam.cmTaskHandle = task;

    int32_t hr = OSALExtensionExecute(CM_FN_CMDEVICE_DESTROYTASK,
                                      &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(hr);
    CHK_FAILURE_RETURN(inParam.returnValue);
    task = nullptr;

    return CM_SUCCESS;

}

//!
//! Create a task queue, CmQueue_RT. It is an in-order queue of tasks. Each task can
//! have multiple kernels running concurrently, each kernel can run in multiple threads.
//! For now only one CmQueue_RT is supported. Trying to create a second CmQueue_RT will fail.
//! Input :
//!     Reference to the pointer to the CmQueue_RT .
//! Output:
//!     CM_SUCCESS if the CmQueue_RT is successfully created;
//!     CM_OUT_OF_HOST_MEMORY if out of system memory;
//!     CM_FAILURE otherwise;
//!
CM_RT_API int32_t CmDevice_RT::CreateQueue( CmQueue* & queue )
{
    INSERT_PROFILER_RECORD();

    // For legacy CreateQueue API, we will only return the same queue
    m_criticalSectionQueue.Acquire();
    for (auto iter = m_queue.begin(); iter != m_queue.end(); iter++)
    {
        CM_QUEUE_TYPE queueType = (*iter)->GetQueueOption().QueueType;
        if (queueType == CM_QUEUE_TYPE_RENDER)
        {
            queue = (*iter);
            m_criticalSectionQueue.Release();
            return CM_SUCCESS;
        }
    }
    m_criticalSectionQueue.Release();

    int32_t result = CreateQueueEx( queue, CM_DEFAULT_QUEUE_CREATE_OPTION);

#if USE_EXTENSION_CODE
    GTPIN_MAKER_FUNCTION(CmrtCodeMarkerForGTPin_CreateQueue(this, queue));
#endif

    return result;
}

CM_RT_API int32_t CmDevice_RT::CreateQueueEx(CmQueue *&queue, CM_QUEUE_CREATE_OPTION queueCreateOption)
{
    INSERT_PROFILER_RECORD();

    m_criticalSectionQueue.Acquire();
    CmQueue_RT *queueRT = nullptr;
    int32_t result = CmQueue_RT::Create(this, queueRT, queueCreateOption);
    if (result != CM_SUCCESS)
    {
        CmAssert(0);
        CmDebugMessage(("Failed to create queue!"));
        m_criticalSectionQueue.Release();
        return result;
    }

    m_queue.push_back(queueRT);
    m_criticalSectionQueue.Release();

    if (queueRT != nullptr)
    {
        queue = static_cast< CmQueue* >(queueRT);
    }
    return result;
}

CM_RT_API int32_t CmDevice_RT::CreateThreadSpace( uint32_t width, uint32_t height, CmThreadSpace* &threadSpace)
{
    INSERT_PROFILER_RECORD();

    CM_CREATETHREADSPACE_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_CREATETHREADSPACE_PARAM ) );
    inParam.tsWidth  = width;
    inParam.tsHeight = height;

    int32_t hr = OSALExtensionExecute(CM_FN_CMDEVICE_CREATETHREADSPACE,
                                      &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(hr);
    CHK_FAILURE_RETURN(inParam.returnValue);
    threadSpace = (CmThreadSpace *)inParam.cmTsHandle;

    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::DestroyThreadSpace( CmThreadSpace* &threadSpace)
{
    INSERT_PROFILER_RECORD();

    CM_DESTROYTHREADSPACE_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_DESTROYTHREADSPACE_PARAM ) );
    inParam.cmTsHandle = threadSpace;

    int32_t hr = OSALExtensionExecute(CM_FN_CMDEVICE_DESTROYTHREADSPACE,
                                      &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(hr);
    CHK_FAILURE_RETURN(inParam.returnValue);
    threadSpace = nullptr;
    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::CreateVmeSurfaceG7_5( CmSurface2D* currentSurface,
                                                 CmSurface2D **forwardSurfaceArray,
                                                 CmSurface2D **backwardSurfaceArray,
                                                 const uint32_t surfaceCountForward,
                                                 const uint32_t surfaceCountBackward,
                                                 SurfaceIndex* & vmeSurfaceIndex )
{
    INSERT_PROFILER_RECORD();

    return CreateVmeSurface( currentSurface, forwardSurfaceArray, backwardSurfaceArray, surfaceCountForward, surfaceCountBackward, vmeSurfaceIndex, CM_FN_CMDEVICE_CREATEVMESURFACEG7_5 );
}

CM_RT_API int32_t CmDevice_RT::DestroyVmeSurfaceG7_5( SurfaceIndex* & vmeSurfaceIndex )
{
    INSERT_PROFILER_RECORD();

    return DestroyVmeSurface( vmeSurfaceIndex );
}

CM_RT_API int32_t CmDevice_RT::SetVmeSurfaceStateParam(SurfaceIndex* vmeIndex, CM_VME_SURFACE_STATE_PARAM *surfStateParam)
{
    INSERT_PROFILER_RECORD();

    if(vmeIndex == nullptr || surfStateParam == nullptr)
    {
        CmAssert( 0 );
        return CM_INVALID_ARG_VALUE;
    }

    CM_CONFIGVMESURFACEDIMENSION_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_CONFIGVMESURFACEDIMENSION_PARAM ) );
    inParam.cmVmeSurfHandle = (void *)vmeIndex;
    inParam.surfDimPara = surfStateParam;

    int32_t result
        = OSALExtensionExecute(CM_FN_CMDEVICE_CONFIGVMESURFACEDIMENSION,
                               &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(result);

    return inParam.returnValue;
}

CM_RT_API int32_t CmDevice_RT::CreateSampler( const CM_SAMPLER_STATE& samplerState, CmSampler* &sampler )
{
    INSERT_PROFILER_RECORD();

    CM_CREATESAMPLER_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_CREATESAMPLER_PARAM ) );
    inParam.samplerState = samplerState;

    int32_t result = OSALExtensionExecute(CM_FN_CMDEVICE_CREATESAMPLER,
                                          &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(result);
    CHK_FAILURE_RETURN(inParam.returnValue);
    sampler = (CmSampler *)inParam.cmSamplerHandle;

    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::CreateSamplerEx( const CM_SAMPLER_STATE_EX& samplerState, CmSampler* &sampler )
{
    INSERT_PROFILER_RECORD();

    CM_CREATESAMPLER_PARAM_EX inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_CREATESAMPLER_PARAM_EX ) );
    inParam.samplerState = samplerState;

    int32_t result = OSALExtensionExecute(CM_FN_CMDEVICE_CREATESAMPLER_EX,
                                          &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(result);
    CHK_FAILURE_RETURN(inParam.returnValue);
    sampler = (CmSampler *)inParam.cmSamplerHandle;

    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::DestroySampler( CmSampler* &sampler )
{
    INSERT_PROFILER_RECORD();

    CM_DESTROYSAMPLER_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_DESTROYSAMPLER_PARAM ) );
    inParam.cmSamplerHandle = sampler;

    int32_t result = OSALExtensionExecute(CM_FN_CMDEVICE_DESTROYSAMPLER,
                                          &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(result);
    CHK_FAILURE_RETURN(inParam.returnValue);
    sampler = nullptr;

    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::CreateThreadGroupSpace( uint32_t threadSpaceWidth, uint32_t threadSpaceHeight, uint32_t groupSpaceWidth, uint32_t groupSpaceHeight, CmThreadGroupSpace* &threadGroupSpace)
{
    INSERT_PROFILER_RECORD();

    CM_CREATETGROUPSPACE_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_CREATETGROUPSPACE_PARAM ) );
    inParam.thrdSpaceWidth  = threadSpaceWidth;
    inParam.thrdSpaceHeight = threadSpaceHeight;
    inParam.thrdSpaceDepth = 1;
    inParam.grpSpaceWidth   = groupSpaceWidth;
    inParam.grpSpaceHeight  = groupSpaceHeight;
    inParam.grpSpaceDepth   = 1;

    int32_t hr = OSALExtensionExecute(CM_FN_CMDEVICE_CREATETHREADGROUPSPACE,
                                      &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(hr);
    CHK_FAILURE_RETURN(inParam.returnValue);
    threadGroupSpace = (CmThreadGroupSpace *)inParam.cmGrpSpaceHandle;

    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::CreateThreadGroupSpaceEx(uint32_t threadSpaceWidth, uint32_t threadSpaceHeight, uint32_t threadSpaceDepth, uint32_t groupSpaceWidth, uint32_t groupSpaceHeight, uint32_t groupSpaceDepth, CmThreadGroupSpace* &threadGroupSpace)
{
    INSERT_PROFILER_RECORD();

    CM_CREATETGROUPSPACE_PARAM inParam;
    CmSafeMemSet(&inParam, 0, sizeof(CM_CREATETGROUPSPACE_PARAM));
    inParam.thrdSpaceWidth = threadSpaceWidth;
    inParam.thrdSpaceHeight = threadSpaceHeight;
    inParam.thrdSpaceDepth = threadSpaceDepth;
    inParam.grpSpaceWidth = groupSpaceWidth;
    inParam.grpSpaceHeight = groupSpaceHeight;
    inParam.grpSpaceDepth = groupSpaceDepth;

    int32_t hr = OSALExtensionExecute(CM_FN_CMDEVICE_CREATETHREADGROUPSPACE,
                                      &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(hr);
    CHK_FAILURE_RETURN(inParam.returnValue);
    threadGroupSpace = (CmThreadGroupSpace *)inParam.cmGrpSpaceHandle;

    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::DestroyThreadGroupSpace(CmThreadGroupSpace* &threadGroupSpace)
{
    INSERT_PROFILER_RECORD();

    CM_DESTROYTGROPUSPACE_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_DESTROYTGROPUSPACE_PARAM ) );
    inParam.cmGrpSpaceHandle = threadGroupSpace;

    int32_t hr = OSALExtensionExecute(CM_FN_CMDEVICE_DESTROYTHREADGROUPSPACE,
                                      &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(hr);
    CHK_FAILURE_RETURN(inParam.returnValue);
    threadGroupSpace = nullptr;
    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::GetCaps(CM_DEVICE_CAP_NAME capName, size_t& capValueSize, void* capValue )
{
    INSERT_PROFILER_RECORD();

    CM_GETCAPS_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_GETCAPS_PARAM ) );
    inParam.capName         = capName;
    inParam.capValueSize    = (uint32_t)capValueSize;
    inParam.capValue        = capValue;

    int32_t result = OSALExtensionExecute(CM_FN_CMDEVICE_GETCAPS,
                                          &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(result);
    CHK_FAILURE_RETURN(inParam.returnValue);
    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::CreateSurface3D(uint32_t width, uint32_t height, uint32_t depth, CM_SURFACE_FORMAT format, CmSurface3D* & surface )
{
    INSERT_PROFILER_RECORD();

    return m_surfaceManager->CreateSurface3D( width,  height,  depth,  format, surface);
}

CM_RT_API int32_t CmDevice_RT::CreateSampler8x8(const CM_SAMPLER_8X8_DESCR  &samplerDescriptor, CmSampler8x8* &sampler)
{
    INSERT_PROFILER_RECORD();

    if((samplerDescriptor.stateType == CM_SAMPLER8X8_AVS && samplerDescriptor.avs == nullptr) ||
        (samplerDescriptor.stateType == CM_SAMPLER8X8_CONV && samplerDescriptor.conv == nullptr) ||
        (samplerDescriptor.stateType == CM_SAMPLER8X8_CONV1DH && samplerDescriptor.conv == nullptr) ||
        (samplerDescriptor.stateType == CM_SAMPLER8X8_CONV1DV && samplerDescriptor.conv == nullptr) ||
        (samplerDescriptor.stateType == CM_SAMPLER8X8_MISC && samplerDescriptor.misc == nullptr) ||
        (samplerDescriptor.stateType == CM_SAMPLER8X8_NONE && samplerDescriptor.conv != nullptr) ||
        sampler != nullptr)
    {
        CmAssert( 0 );
        return CM_INVALID_ARG_VALUE;
    }

    CM_CREATESAMPLER8x8_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_CREATESAMPLER8x8_PARAM ) );
    inParam.sampler8x8Desc = samplerDescriptor;

    int32_t result = OSALExtensionExecute(CM_FN_CMDEVICE_CREATESAMPLER8X8,
                                          &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(result);
    CHK_FAILURE_RETURN(inParam.returnValue);
    sampler = (CmSampler8x8 *)inParam.cmSampler8x8Handle;

    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::DestroySampler8x8( CmSampler8x8 *& sampler8x8 )
{
    INSERT_PROFILER_RECORD();

    CM_DESTROYSAMPLER8x8_PARAM inParam;

    CmSafeMemSet( &inParam, 0, sizeof( CM_DESTROYSAMPLER8x8_PARAM ) );
    inParam.cmSampler8x8Handle = sampler8x8;

    int32_t result = OSALExtensionExecute(CM_FN_CMDEVICE_DESTROYSAMPLER8X8,
                                          &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(result);
    CHK_FAILURE_RETURN(inParam.returnValue);
    sampler8x8 = nullptr;

    return CM_SUCCESS;
}

 CM_RT_API int32_t CmDevice_RT::CreateSampler8x8Surface(CmSurface2D* surface2d, SurfaceIndex* &sampler8x8SurfaceIndex, CM_SAMPLER8x8_SURFACE surfaceType, CM_SURFACE_ADDRESS_CONTROL_MODE addressControl)
 {
     INSERT_PROFILER_RECORD();

    CmSurface2D* currentRT = static_cast< CmSurface2D* >( surface2d );
    if( ! currentRT )  {
        CmAssert( 0 );
        return CM_FAILURE;
    }

    CM_CREATESAMPLER8x8SURF_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_CREATESAMPLER8x8SURF_PARAM ) );
    inParam.cmSurf2DHandle   = currentRT;
    inParam.cmSampler8x8Type = surfaceType;
    inParam.sampler8x8Mode   = addressControl;

    int32_t result
        = OSALExtensionExecute(CM_FN_CMDEVICE_CREATESAMPLER8X8SURFACE,
                               &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(result);
    CHK_FAILURE_RETURN(inParam.returnValue);
    sampler8x8SurfaceIndex = inParam.cmSurfIndexHandle;

    return CM_SUCCESS;
 }

 CM_RT_API int32_t CmDevice_RT::CreateSampler8x8SurfaceEx(CmSurface2D* surface2d, SurfaceIndex* &sampler8x8SurfaceIndex, CM_SAMPLER8x8_SURFACE surfaceType, CM_SURFACE_ADDRESS_CONTROL_MODE addressControl, CM_FLAG* flag)
 {
     INSERT_PROFILER_RECORD();

     CmSurface2D* currentRT = static_cast< CmSurface2D* >(surface2d);
     if (!currentRT)  {
         CmAssert(0);
         return CM_FAILURE;
     }

     CM_CREATESAMPLER8x8SURFEX_PARAM inParam;
     CmSafeMemSet(&inParam, 0, sizeof(inParam));
     inParam.cmSurf2DHandle = currentRT;
     inParam.cmSampler8x8Type = surfaceType;
     inParam.sampler8x8Mode = addressControl;
     inParam.flag = flag;

     int32_t result
         = OSALExtensionExecute(CM_FN_CMDEVICE_CREATESAMPLER8X8SURFACE_EX,
                                &inParam, sizeof(inParam));

     CHK_FAILURE_RETURN(result);
     CHK_FAILURE_RETURN(inParam.returnValue);
     sampler8x8SurfaceIndex = inParam.cmSurfIndexHandle;

     return CM_SUCCESS;
 }

 CM_RT_API int32_t CmDevice_RT::CreateSamplerSurface2DEx(CmSurface2D* surface2d, SurfaceIndex* & samplerSurface2dIndex, CM_FLAG* flag)
 {
     INSERT_PROFILER_RECORD();

     CmSurface2D* surface2dRT = static_cast< CmSurface2D* >(surface2d);
     if (!surface2dRT)  {
         CmAssert(0);
         return CM_INVALID_ARG_VALUE;
     }

     CM_CREATESAMPLER2DEX_PARAM inParam;
     CmSafeMemSet(&inParam, 0, sizeof(inParam));
     inParam.cmSurface2DHandle = surface2dRT;
     inParam.flag = flag;

     int32_t result
         = OSALExtensionExecute(CM_FN_CMDEVICE_CREATESAMPLERSURFACE2D_EX,
                                &inParam, sizeof(inParam));

     CHK_FAILURE_RETURN(result);
     CHK_FAILURE_RETURN(inParam.returnValue);
     samplerSurface2dIndex = (SurfaceIndex*)inParam.samplerSurfIndexHandle;
     return CM_SUCCESS;
 }

CM_RT_API int32_t CmDevice_RT::DestroySampler8x8Surface(SurfaceIndex* &sampler8x8SurfaceIndex)
{
    INSERT_PROFILER_RECORD();

    CM_DESTROYSAMPLER8x8SURF_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_DESTROYSAMPLER8x8SURF_PARAM ) );
    inParam.cmSurfIndexHandle = sampler8x8SurfaceIndex;

    int32_t result
        = OSALExtensionExecute(CM_FN_CMDEVICE_DESTROYSAMPLER8X8SURFACE,
                               &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(result);
    CHK_FAILURE_RETURN(inParam.returnValue);
    sampler8x8SurfaceIndex = nullptr;

    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::SetL3Config(const L3ConfigRegisterValues *registerValues)
{
    INSERT_PROFILER_RECORD();

    m_l3Config = *registerValues;

    SetCapsInternal(CAP_L3_CONFIG, sizeof(L3ConfigRegisterValues), &m_l3Config);

    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::SetSuggestedL3Config( L3_SUGGEST_CONFIG configIndex)
{
    INSERT_PROFILER_RECORD();

    //Call into UMD
    CM_DEVICE_SETSUGGESTEDL3_PARAM setL3IndexParam;
    CmSafeMemSet(&setL3IndexParam, 0 , sizeof(CM_DEVICE_SETSUGGESTEDL3_PARAM));
    setL3IndexParam.l3SuggestConfig = configIndex;

    int32_t result = OSALExtensionExecute(CM_FN_CMDEVICE_SETSUGGESTEDL3CONFIG,
                                          &setL3IndexParam,
                                          sizeof(setL3IndexParam));

    CHK_FAILURE_RETURN(result);
    CHK_FAILURE_RETURN(setL3IndexParam.returnValue);
    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::SetCaps(CM_DEVICE_CAP_NAME capName, size_t capValueSize, void* capValue )
{
    INSERT_PROFILER_RECORD();

    switch(capName)
    {
    case CAP_HW_THREAD_COUNT:
        return SetCapsInternal(capName, capValueSize, capValue);

    default:
        return CM_INVALID_CAP_NAME;
    }
}

int32_t CmDevice_RT::SetCapsInternal(CM_DEVICE_CAP_NAME capName, size_t capValueSize, void* capValue)
{

    //Call into UMD
    CM_DEVICE_SETCAP_PARAM setCapParam;
    CmSafeMemSet(&setCapParam, 0 , sizeof(setCapParam));
    setCapParam.capName = capName;
    setCapParam.capValueSize = capValueSize;
    setCapParam.capValue = capValue;

    int32_t result = OSALExtensionExecute(CM_FN_CMDEVICE_SETCAPS,
                                          &setCapParam, sizeof(setCapParam));

    CHK_FAILURE_RETURN(result);
    CHK_FAILURE_RETURN(setCapParam.returnValue);
    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::CreateSamplerSurface2D(CmSurface2D* surface2d, SurfaceIndex* & samplerSurface2dIndex)
{
    INSERT_PROFILER_RECORD();

    CmSurface2D* surface2dRT = static_cast< CmSurface2D* >( surface2d );
    if( ! surface2dRT )  {
        CmAssert( 0 );
        return CM_FAILURE;
    }

    CM_CREATESAMPLER2D_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_CREATESAMPLER2D_PARAM ) );
    inParam.cmSurface2DHandle  = surface2dRT;

    int32_t result
        = OSALExtensionExecute(CM_FN_CMDEVICE_CREATESAMPLERSURFACE2D,
                               &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(result);
    CHK_FAILURE_RETURN(inParam.returnValue);
    samplerSurface2dIndex = (SurfaceIndex* )inParam.samplerSurfIndexHandle;
    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::CreateSamplerSurface2DUP(CmSurface2DUP* surface2dUP, SurfaceIndex* & samplerSurface2dUPIndex)
{
    INSERT_PROFILER_RECORD();

    CM_CREATESAMPLER2DUP_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_CREATESAMPLER2DUP_PARAM ) );
    inParam.cmSurface2DHandle = surface2dUP;

    int32_t result
        = OSALExtensionExecute(CM_FN_CMDEVICE_CREATESAMPLERSURFACE2DUP,
                               &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(result);
    CHK_FAILURE_RETURN(inParam.returnValue);
    samplerSurface2dUPIndex = (SurfaceIndex* )inParam.samplerSurfIndexHandle;
    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::CreateSamplerSurface3D(CmSurface3D* surface3d, SurfaceIndex* & samplerSurface3dIndex)
{
    INSERT_PROFILER_RECORD();

    CM_CREATESAMPLER3D_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_CREATESAMPLER3D_PARAM ) );
    inParam.cmSurface3DHandle  = surface3d;

    int32_t result
        = OSALExtensionExecute(CM_FN_CMDEVICE_CREATESAMPLERSURFACE3D,
                               &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(result);
    CHK_FAILURE_RETURN(inParam.returnValue);
    samplerSurface3dIndex = (SurfaceIndex* )inParam.samplerSurfIndexHandle;
    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::DestroySamplerSurface(SurfaceIndex* & samplerSurfaceIndex)
{
    INSERT_PROFILER_RECORD();

    CM_DESTROYSAMPLERSURF_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_DESTROYSAMPLERSURF_PARAM ) );
    inParam.samplerSurfIndexHandle = samplerSurfaceIndex;

    int32_t result = OSALExtensionExecute(CM_FN_CMDEVICE_DESTROYSAMPLERSURFACE,
                                          &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(result);
    CHK_FAILURE_RETURN(inParam.returnValue);

    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT:: DestroySurface( CmSurface3D* &surface3d)
{
    INSERT_PROFILER_RECORD();

    return m_surfaceManager->DestroySurface3D(surface3d);
}

int32_t CmDevice_RT::CheckDdiVersionSupported(const uint32_t ddiVersion)
{
    if( ( ddiVersion >= CM_DDI_7_2 ))
    {
        return CM_SUCCESS;
    }
    else
    {
        return CM_UMD_DRIVER_NOT_SUPPORTED;
    }
}

CM_RT_API int32_t CmDevice_RT::InitPrintBuffer(size_t size)
{
    INSERT_PROFILER_RECORD();

    CM_DEVICE_INIT_PRINT_BUFFER_PARAM initPrintBufferParam;
    CmSafeMemSet(&initPrintBufferParam, 0, sizeof(CM_DEVICE_INIT_PRINT_BUFFER_PARAM));
    initPrintBufferParam.printBufferSize = (uint32_t)size;

    int32_t hr = OSALExtensionExecute(CM_FN_CMDEVICE_INIT_PRINT_BUFFER,
                                      &initPrintBufferParam,
                                      sizeof(initPrintBufferParam));

    CHK_FAILURE_RETURN(hr);
    CHK_FAILURE_RETURN(initPrintBufferParam.returnValue);

    m_printBuffer = (unsigned char *)initPrintBufferParam.printBufferMem;
    m_printEnabled   = true;
    m_printBufferSize = size;

    return CM_SUCCESS;
}

//*-----------------------------------------------------------------------------
//| Purpose:    Flush the print buffer and dump it on the file
//| Returns:    result of operation.
//*-----------------------------------------------------------------------------
CM_RT_API  int32_t CmDevice_RT::FlushPrintBufferIntoFile(const char *filename)
{
    INSERT_PROFILER_RECORD();

    return FlushPrintBufferInternal(filename);
}

//*-----------------------------------------------------------------------------
//| Purpose:    Flush the print buffer and dump it on stdout
//| Returns:    result of operation.
//*-----------------------------------------------------------------------------
CM_RT_API int32_t CmDevice_RT::FlushPrintBuffer()
{
    INSERT_PROFILER_RECORD();

    return FlushPrintBufferInternal(nullptr);
}

//*-----------------------------------------------------------------------------
//| Purpose:    Internal function to flush print buffer on stdout or file.
//| Returns:    result of operation.
//*-----------------------------------------------------------------------------
 int32_t CmDevice_RT::FlushPrintBufferInternal(const char *filename)
{
    FILE * streamout = nullptr;

    if (filename == nullptr)
    {
        streamout = stdout;
    }
    else
    {
        CM_FOPEN(streamout, filename, "wb");
        if (streamout == nullptr)
        {
            //Open file Failed
            CmAssert(0);
            return CM_FAILURE;
        }
    }

    if( m_printBuffer == nullptr ||
        m_printBufferSize == 0      ||
        m_printEnabled == false    )
    {
        CmAssert(0);
        if (filename)
        {
            fclose(streamout);
        }
        return CM_FAILURE;
    }

    //Dump memory on the screen.
    DumpAllThreadOutput(streamout, m_printBuffer, m_printBufferSize);

    //Flush and close stream
    fflush(streamout);
    if (filename)
        fclose(streamout);

    //clean memory
    CmSafeMemSet(m_printBuffer, 0, m_printBufferSize);
    *(unsigned int*)m_printBuffer = sizeof(CM_PRINT_HEADER);

    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::CreateVebox( CmVebox* & vebox )
{
    INSERT_PROFILER_RECORD();

    CM_CREATEVEBOX_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_CREATEVEBOX_PARAM ) );

    int32_t hr = OSALExtensionExecute(CM_FN_CMDEVICE_CREATEVEBOX,
                                      &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(hr);
    CHK_FAILURE_RETURN(inParam.returnValue);
    vebox = (CmVebox *)inParam.cmVeboxHandle;
    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::DestroyVebox( CmVebox* & vebox )
{
    INSERT_PROFILER_RECORD();

    CM_DESTROYVEBOX_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( inParam ) );
    inParam.cmVeboxHandle = vebox;

    int32_t hr = OSALExtensionExecute(CM_FN_CMDEVICE_DESTROYVEBOX,
                                      &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(hr);
    CHK_FAILURE_RETURN(inParam.returnValue);
    vebox = nullptr;
    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::CreateBufferSVM(uint32_t size, void* &sysMem, uint32_t accessFlag, CmBufferSVM* & buffer)
{
    INSERT_PROFILER_RECORD();

    return m_surfaceManager->CreateBufferSVM(size, sysMem, accessFlag, buffer);
}

CM_RT_API int32_t CmDevice_RT::DestroyBufferSVM( CmBufferSVM* &buffer)
{
    INSERT_PROFILER_RECORD();

    return m_surfaceManager->DestroyBufferSVM(buffer);
}

CM_RT_API int32_t CmDevice_RT::CreateSurface2DAlias(CmSurface2D* originalSurface, SurfaceIndex* &aliasIndex)
{
    INSERT_PROFILER_RECORD();

    CM_DEVICE_CREATE_SURF2D_ALIAS_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof(inParam) );

    inParam.cmSurface2DHandle  = originalSurface;
    inParam.surfaceIndexHandle = aliasIndex;

    int32_t hr = OSALExtensionExecute(CM_FN_CMDEVICE_CREATESURFACE2D_ALIAS,
                                      &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(hr);
    CHK_FAILURE_RETURN(inParam.returnValue);
    aliasIndex = (SurfaceIndex*)inParam.surfaceIndexHandle;

    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::CreateBufferAlias(CmBuffer *originalBuffer, SurfaceIndex* &aliasIndex)
{
    INSERT_PROFILER_RECORD();

    CM_DEVICE_CREATE_BUFFER_ALIAS_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof(inParam) );

    inParam.cmBufferHandle = originalBuffer;
    inParam.surfaceIndexHandle = aliasIndex;

    int32_t hr = OSALExtensionExecute(CM_FN_CMDEVICE_CREATEBUFFER_ALIAS,
                                      &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(hr);
    CHK_FAILURE_RETURN(inParam.returnValue);
    aliasIndex = (SurfaceIndex*)inParam.surfaceIndexHandle;

    return CM_SUCCESS;
}

//*-----------------------------------------------------------------------------
//| Purpose:    Duplicate the kernel member values
//| Arguments :
//|             destKernel     [in/out]    pointer to output kernel, must be nullptr
//|             srcKernel      [in]        pointer to input kernel
//|
//| Returns:    Result of the operation.
//*-----------------------------------------------------------------------------
CM_RT_API int32_t CmDevice_RT::CloneKernel( CmKernel * &destKernel, CmKernel *srcKernel )
{
    INSERT_PROFILER_RECORD();

    CM_CLONE_KERNEL_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_CLONE_KERNEL_PARAM ) );
    inParam.cmKernelHandleSrc  = srcKernel;
    inParam.cmKernelHandleDest = destKernel;

    int32_t hr = OSALExtensionExecute(CM_FN_CMDEVICE_CLONEKERNEL,
                                      &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(hr);
    CHK_FAILURE_RETURN(inParam.returnValue);
    destKernel = (CmKernel *)inParam.cmKernelHandleDest;

    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::CreateHevcVmeSurfaceG10(CmSurface2D* currentSurface, CmSurface2D** forwardSurfaceArray, CmSurface2D** backwardSurfaceArray, const uint32_t surfaceCountForward, const uint32_t surfaceCountBackward, SurfaceIndex* & vmeSurfaceIndex)
{
    INSERT_PROFILER_RECORD();

    return CreateVmeSurface( currentSurface, forwardSurfaceArray, backwardSurfaceArray, surfaceCountForward, surfaceCountBackward, vmeSurfaceIndex, CM_FN_CMDEVICE_CREATEHEVCVMESURFACEG10 );
}

CM_RT_API int32_t CmDevice_RT::DestroyHevcVmeSurfaceG10(SurfaceIndex* & vmeSurfaceIndex)
{
    INSERT_PROFILER_RECORD();

    return DestroyVmeSurface( vmeSurfaceIndex );
}

int32_t CmDevice_RT::CreateVmeSurface( CmSurface2D* currentSurface, CmSurface2D** forwardSurfaceArray, CmSurface2D** backwardSurfaceArray, const uint32_t surfaceCountForward, const uint32_t surfaceCountBackward, SurfaceIndex* & vmeSurfaceIndex, CM_FUNCTION_ID functionName)
{
    if ( currentSurface == nullptr )
    {
        CmAssert( 0 );
        return CM_NULL_POINTER;
    }

    CM_CREATEVMESURFACE_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_CREATEVMESURFACE_PARAM ) );
    inParam.cmCurSurfHandle = currentSurface;
    inParam.cmForwardSurfArray = forwardSurfaceArray;
    inParam.cmBackwardSurfArray = backwardSurfaceArray;
    inParam.forwardSurfCount = surfaceCountForward;
    inParam.backwardSurfCount = surfaceCountBackward;

    int32_t result = OSALExtensionExecute(functionName,
                                          &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(result);
    CHK_FAILURE_RETURN(inParam.returnValue);

    vmeSurfaceIndex = ( SurfaceIndex* )inParam.cmVmeSurfIndexHandle;

    return CM_SUCCESS;
}

int32_t CmDevice_RT::DestroyVmeSurface( SurfaceIndex* & vmeSurfaceIndex )
{
    //Call into driver
    CM_DESTROYVMESURFACE_PARAM inParam;
    CmSafeMemSet( &inParam, 0, sizeof( CM_DESTROYVMESURFACE_PARAM ) );
    inParam.cmVmeSurfIndexHandle = ( void  *)vmeSurfaceIndex;

    int32_t hr = OSALExtensionExecute(CM_FN_CMDEVICE_DESTROYVMESURFACE,
                                      &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(hr);
    CHK_FAILURE_RETURN(inParam.returnValue);
    vmeSurfaceIndex = nullptr;

    return CM_SUCCESS;
}

CM_RT_API int32_t CmDevice_RT::GetVISAVersion(uint32_t& majorVersion, uint32_t& minorVersion)
{
    INSERT_PROFILER_RECORD();

    CM_DEVICE_GET_VISA_VERSION_PARAM inParam;
    CmSafeMemSet(&inParam, 0, sizeof(CM_DEVICE_GET_VISA_VERSION_PARAM));

    int32_t hr = OSALExtensionExecute(CM_FN_CMDEVICE_GETVISAVERSION,
                                      &inParam, sizeof(inParam));

    CHK_FAILURE_RETURN(hr);
    CHK_FAILURE_RETURN(inParam.returnValue);
    majorVersion = inParam.majorVersion;
    minorVersion = inParam.minorVersion;
    return CM_SUCCESS;
}
