/*
* This copyright notice applies to this header file only:
*
* Copyright (c) 2018 NVIDIA 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.
*/
/**
* \file nvOpticalFlowCommon.h
*   NVIDIA GPUs - Turing and above contains a hardware-based optical flow engine
*   which provides fully-accelerated hardware-based optical flow and stereo estimation.
*   nvOpticalFlowCommon.h provides enums, structure definitions and function prototypes which are common across different devices,
*   nvOpticalFlowCommon.h uses #pragma directives to pack structure members with one byte alignment.
* \date 2018
*  nvOpticalFlowCommon.h provides common enums, structure definitions and function prototypes.
*/

/**
 * \file src/opr/impl/nvof/nvOpticalFlowCommon.h
 * MegEngine is Licensed under the Apache License, Version 2.0 (the "License")
 *
 * Copyright (c) 2014-2020 Megvii Inc. All rights reserved.
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 */

#include "megbrain_build_config.h"

#if MGB_CUDA
#ifndef _NV_OPTICALFLOW_COMMON_H_
#define _NV_OPTICALFLOW_COMMON_H_
#if defined(_MSC_VER_) && (_MSC_VER_ < 1600)
#ifndef _STDINT
typedef __int32             int32_t;
typedef unsigned __int32    uint32_t;
typedef __int64             int64_t;
typedef unsigned __int64    uint64_t;
typedef signed char         int8_t;
typedef unsigned char       uint8_t;
typedef short               int16_t;
typedef unsigned short      uint16_t;
#endif
#else
#include <stdint.h>
#endif

#ifdef _WIN32
#define NVOFAPI __stdcall
#else
#define NVOFAPI
#endif
#define NV_OF_API_MAJOR_VERSION 1
#define NV_OF_API_MINOR_VERSION 1
#define NV_OF_API_VERSION  (uint16_t)((NV_OF_API_MAJOR_VERSION << 4) | NV_OF_API_MINOR_VERSION)
#define MIN_ERROR_STRING_SIZE 80

#if defined(__cplusplus)
extern "C" 
{
#endif /* __cplusplus */

typedef struct NvOFHandle_st            *NvOFHandle;
typedef struct NvOFGPUBufferHandle_st   *NvOFGPUBufferHandle;
typedef struct NVOFPrivDataHandle_st    *NvOFPrivDataHandle;

/**
  *  Supported error codes
*/
typedef enum _NV_OF_STATUS
{
    /**
    * This indicates that API call returned with no errors.
    */
    NV_OF_SUCCESS,

    /**
    * This indicates that HW Optical flow functionality is not supported
    */
    NV_OF_ERR_OF_NOT_AVAILABLE,

    /**
    * This indicates that device passed by the client is not supported.
    */
    NV_OF_ERR_UNSUPPORTED_DEVICE,

    /**
    * This indicates that device passed to the API call is no longer available and
    * needs to be reinitialized.
    */
    NV_OF_ERR_DEVICE_DOES_NOT_EXIST,

    /**
    * This indicates that one or more of the pointers passed to the API call
    * is invalid.
    */
    NV_OF_ERR_INVALID_PTR,

    /**
    * This indicates that one or more of the parameter passed to the API call
    * is invalid.
    */
    NV_OF_ERR_INVALID_PARAM,

    /**
    * This indicates that an API call was made in wrong sequence/order.
    */
    NV_OF_ERR_INVALID_CALL,

    /**
    * This indicates that an invalid struct version was used by the client.
    */
    NV_OF_ERR_INVALID_VERSION,

    /**
    * This indicates that the API call failed because it was unable to allocate
    * enough memory to perform the requested operation.
    */
    NV_OF_ERR_OUT_OF_MEMORY,

    /**
    * This indicates that the OF session has not been initialized with
    * ::NvOFInit() or that initialization has failed.
    */
    NV_OF_ERR_NOT_INITIALIZED,

    /**
    * This indicates that an unsupported parameter was passed by the client.
    */
    NV_OF_ERR_UNSUPPORTED_FEATURE,

    /**
    * This indicates that an unknown internal error has occurred.
    */
   NV_OF_ERR_GENERIC,
} NV_OF_STATUS;

/**
*  Supported bool values
*/
typedef enum _NV_OF_BOOL
{
    NV_OF_FALSE = 0,                              /* < Represents false bool value */
    NV_OF_TRUE  = !NV_OF_FALSE                    /* < Represents true bool value */
} NV_OF_BOOL;

/**
* Supported optical flow and stereo disparity capability values.
*/
typedef enum _NV_OF_CAPS
{
    NV_OF_CAPS_SUPPORTED_OUTPUT_GRID_SIZES,      /**< Indicates supported values of ::NV_OF_OUTPUT_VECTOR_GRID_SIZE, 
                                                    ::NV_OF_INIT_PARAMS::outGridSize should be set with a supported output gridsize. */
    NV_OF_CAPS_SUPPORTED_HINT_GRID_SIZES,        /**< Indicates supported values of ::NV_OF_HINT_VECTOR_GRID_SIZE, 
                                                    ::NV_OF_INIT_PARAMS::hintGridSize should be set with a supported hint gridsize. */
    NV_OF_CAPS_SUPPORT_HINT_WITH_OF_MODE,        /**< Indicates external hint support for ::NV_OF_MODE_OPTICALFLOW mode. 
                                                    0: External hint not supported for ::NV_OF_MODE_OPTICALFLOW mode.
                                                    1: External hint is supported for ::NV_OF_MODE_OPTICALFLOW mode. */ 
    NV_OF_CAPS_SUPPORT_HINT_WITH_ST_MODE         /**< Indicates external hint support for ::NV_OF_MODE_STEREODISPARITY mode. 
                                                    0: External hint not supported for ::NV_OF_MODE_STEREODISPARITY mode.
                                                    1: External hint is supported for ::NV_OF_MODE_STEREODISPARITY mode. */ 
} NV_OF_CAPS;

/**
* Supported optical flow/stereo disparity performance levels.
*/
typedef enum _NV_OF_PERF_LEVEL
{
    NV_OF_PERF_LEVEL_UNDEFINED,
    NV_OF_PERF_LEVEL_SLOW = 5,                   /**< Slow perf level results in lowest performance and best quality */
    NV_OF_PERF_LEVEL_MEDIUM = 10,                /**< Medium perf level results in low performance and medium quality */
    NV_OF_PERF_LEVEL_FAST = 20,                  /**< Fast perf level results in high performance and low quality */
    NV_OF_PERF_LEVEL_MAX
} NV_OF_PERF_LEVEL;

/**
* Supported grid size for output buffer ::NV_OF_EXECUTE_PARAMS::outputBuffer.
* Client should set ::NV_OF_INIT_PARAMS::outGridSize with ::NV_OF_OUTPUT_VECTOR_GRID_SIZE values.
*/
typedef enum _NV_OF_OUTPUT_VECTOR_GRID_SIZE
{
    NV_OF_OUTPUT_VECTOR_GRID_SIZE_UNDEFINED,
    NV_OF_OUTPUT_VECTOR_GRID_SIZE_4 = 4,          /**< Output buffer grid size is 4x4  */
    NV_OF_OUTPUT_VECTOR_GRID_SIZE_MAX
} NV_OF_OUTPUT_VECTOR_GRID_SIZE;

/**
* Expected grid size for optional paramater ::NV_OF_EXECUTE_PARAMS::externalHints buffer.
* Client should set ::NV_OF_INIT_PARAMS::hintGridSize with ::NV_OF_HINT_VECTOR_GRID_SIZE values.
*/
typedef enum _NV_OF_HINT_VECTOR_GRID_SIZE
{
    NV_OF_HINT_VECTOR_GRID_SIZE_UNDEFINED,
    NV_OF_HINT_VECTOR_GRID_SIZE_4 = 4,            /**< Hint buffer grid size is 4x4.*/
    NV_OF_HINT_VECTOR_GRID_SIZE_8 = 8,            /**< Hint buffer grid size is 8x8.*/
    NV_OF_HINT_VECTOR_GRID_SIZE_MAX
} NV_OF_HINT_VECTOR_GRID_SIZE;

/**
* ::NV_OF_MODE enum define values for Optical flow and Stereo disparity modes.
* Client need to set ::NV_OF_INIT_PARAMS::mode with ::NV_OF_MODE values.
* For the ::NV_OF_MODE_OPTICALFLOW mode, the buffer format for ::NV_OF_EXECUTE_PARAMS::externalHints
* and ::NV_OF_EXECUTE_PARAMS::outputBuffer is ::NV_OF_FLOW_VECTOR.
* For the ::NV_OF_MODE_STEREODISPARITY mode, the buffer format for ::NV_OF_EXECUTE_PARAMS::externalHints
* and ::NV_OF_EXECUTE_PARAMS::outputBuffer is ::NV_OF_STEREO_DISPARITY.
*/
typedef enum _NV_OF_MODE
{
    NV_OF_MODE_UNDEFINED,
    NV_OF_MODE_OPTICALFLOW,                       /**< Calculate optical flow between two frames. */
    NV_OF_MODE_STEREODISPARITY,                   /**< Calculate disparity between Stereo view pair. */
    NV_OF_MODE_MAX
} NV_OF_MODE;

/**
*  Supported buffer type for ::NvOFGPUBufferHandle allocation.
*  Client need to set NV_OF_CREATE_BUFFER::bufferUsage with ::NV_OF_BUFFER_USAGE enum values.
*/
typedef enum _NV_OF_BUFFER_USAGE
{
    NV_OF_BUFFER_USAGE_UNDEFINED,
    NV_OF_BUFFER_USAGE_INPUT,                    /**< Input buffer type is used to allocate ::NV_OF_INPUT_EXECUTE_PARAMS::inputFrame,
                                                      ::NV_OF_INPUT_EXECUTE_PARAMS::referenceFrame. */
    NV_OF_BUFFER_USAGE_OUTPUT,                   /**< Output buffer type is used to allocate ::NV_OF_OUTPUT_EXECUTE_PARAMS::outputBuffer. */
    NV_OF_BUFFER_USAGE_HINT,                     /**< Hint buffer type is used to allocate ::NV_OF_INPUT_EXECUTE_PARAMS::externalHints.*/
    NV_OF_BUFFER_USAGE_COST,                     /**< Cost buffer type is used to allocate ::NV_OF_OUTPUT_EXECUTE_PARAMS::outputCostBuffer.*/
    NV_OF_BUFFER_USAGE_MAX
} NV_OF_BUFFER_USAGE;

/**
* Supported buffer formats
*/
typedef enum _NV_OF_BUFFER_FORMAT
{
    NV_OF_BUFFER_FORMAT_UNDEFINED,
    NV_OF_BUFFER_FORMAT_GRAYSCALE8,               /**< Input buffer format with 8 bit planar format */
    NV_OF_BUFFER_FORMAT_NV12,                     /**< Input buffer format with 8 bit plannar, UV interleaved */
    NV_OF_BUFFER_FORMAT_ABGR8,                    /**< Input buffer format with 8 bit packed A8B8G8R8 */
    NV_OF_BUFFER_FORMAT_SHORT,                    /**< Output or hint buffer format for stereo disparity */
    NV_OF_BUFFER_FORMAT_SHORT2,                   /**< Output or hint buffer format for optical flow vector */
    NV_OF_BUFFER_FORMAT_UINT,                     /**< Cost buffer format for optical flow vector / stereo disparity */
    NV_OF_BUFFER_FORMAT_MAX
} NV_OF_BUFFER_FORMAT;

/**
* \struct NV_OF_FLOW_VECTOR
* Struct needed for optical flow. ::NV_OF_EXECUTE_OUTPUT_PARAMS::outputBuffer will be populated with optical flow
* in ::NV_OF_FLOW_VECTOR format for each ::NV_OF_INIT_PARAMS::outGridSize.
* Flow vectors flowx and flowy are 16-bit values with the lowest 5 bits holding fractional value,
* followed by a 10-bit integer value and the most significant bit being a sign bit.
*/
typedef struct _NV_OF_FLOW_VECTOR
{
    int16_t                         flowx;        /**< x component of flow in S10.5 format */
    int16_t                         flowy;        /**< y component of flow in S10.5 format */
} NV_OF_FLOW_VECTOR;

/**
* \struct NV_OF_STEREO_DISPARITY
* Struct needed for stereo /disparity. ::NV_OF_OUTPUT_EXECUTE_PARAMS::outputBuffer will be populated
* with stereo disparity in ::NV_OF_STEREO_DISPARITY format for each ::NV_OF_INIT_PARAMS::outGridSize.
* Stereo disparity is a 16-bit value with the lowest 5 bits holding fractional value,
* followed by a 11-bit unsigned integer value.
*/
typedef struct _NV_OF_STEREO_DISPARITY
{
    uint16_t                        disparity;    /**< Horizontal displacement[in pixels] in 11.5 format. */
} NV_OF_STEREO_DISPARITY;

/**
* \struct NV_OF_INIT_PARAMS
* Optical flow/stereo disparity session initialization parameters.
*/
typedef struct _NV_OF_INIT_PARAMS
{
    uint32_t                        width;                            /**< [in]: Specifies input buffer width */
    uint32_t                        height;                           /**< [in]: Specifies input buffer height */
    NV_OF_OUTPUT_VECTOR_GRID_SIZE   outGridSize;                      /**< [in]: Specifies flow vector grid size for ::NV_OF_EXECUTE_PARAMS::outputBuffer buffer.*/
    NV_OF_HINT_VECTOR_GRID_SIZE     hintGridSize;                     /**< [in]: Specifies flow vector grid size for ::NV_OF_EXECUTE_PARAMS::externalHints buffer.
                                                                                 This field is only considered if ::NV_OF_INIT_PARAMS::enableExternalHints is set */
    NV_OF_MODE                      mode;                             /**< [in]: Operating mode for NVOF. Set to a value defined by enum ::NV_OF_MODE. */
    NV_OF_PERF_LEVEL                perfLevel;                        /**< [in]: Specifies perf level. */
    NV_OF_BOOL                      enableExternalHints;              /**< [in]: Set to 1 to enable external hints for optical flow session. */
    NV_OF_BOOL                      enableOutputCost;                 /**< [in]: Set to 1 to enable output cost calculation for optical flow session. */
    NvOFPrivDataHandle              hPrivData;                        /**< [in]: Optical flow private data. It is reserved field and should be set to NULL. */
} NV_OF_INIT_PARAMS;

/**
* \struct NV_OF_BUFFER_DESCRIPTOR
* Creation parameters for optical flow buffers.
*/
typedef struct _NV_OF_BUFFER_DESCRIPTOR
{
    uint32_t                        width;                           /**< [in]: Buffer width. */
    uint32_t                        height;                          /**< [in]: Buffer height. */
    NV_OF_BUFFER_USAGE              bufferUsage;                     /**< [in]: To specify buffer usage type.
                                                                     ::NV_OF_BUFFER_USAGE_OUTPUT buffer usage type accepts ::NV_OF_CREATE_BUFFER::width,
                                                                     ::NV_OF_BUFFER_DESCRIPTOR::height in ::NV_OF_INIT_PARAMS::outGridSize units.
                                                                     ::NV_OF_BUFFER_USAGE_HINT buffer usage type accepts ::NV_OF_BUFFER_DESCRIPTOR::width,
                                                                     ::NV_OF_BUFFER_DESCRIPTOR::height in ::NV_OF_INIT_PARAMS::hintGridSize units. */
    NV_OF_BUFFER_FORMAT             bufferFormat;                    /**< [in]: Buffer format. */

} NV_OF_BUFFER_DESCRIPTOR;

/**
* \struct NV_OF_EXECUTE_INPUT_PARAMS
* Parameters which are sent per frame for optical flow/stereo disparity execution.
*/
typedef struct _NV_OF_EXECUTE_INPUT_PARAMS
{
    NvOFGPUBufferHandle             inputFrame;                      /**< [in]: If ::NV_OF_INIT_PARAMS::mode is ::NV_OF_MODE_OPTICALFLOW, this specifies the handle to the buffer containing the input frame.
                                                                                If ::NV_OF_INIT_PARAMS::mode is ::NV_OF_MODE_STEREODISPARITY, this specifies the handle to the buffer containing the rectified left view. */
    NvOFGPUBufferHandle             referenceFrame;                  /**< [in]: If ::NV_OF_INIT_PARAMS::mode is ::NV_OF_MODE_OPTICALFLOW, this specifies the handle to the buffer containing the reference frame.
                                                                                If ::NV_OF_INIT_PARAMS::mode is ::NV_OF_MODE_STEREODISPARITY, this specifies the handle to the buffer containing the rectified right view. */
    NvOFGPUBufferHandle             externalHints;                   /**< [in]: It is an optional input, This field will be considered if client had set ::NV_OF_INIT_PARAMS::enableExternalHint flag.
                                                                                Client can pass some available predictors as hints. 
                                                                                Optical flow driver will search around those hints to optimize flow vectors quality.
                                                                                Expected hint buffer format is ::NV_OF_FLOW_VECTOR, ::NV_OF_STEREO_DISPARITY 
                                                                                for ::NV_OF_MODE_OPTICALFLOW, ::NV_OF_MODE_STEREODISPARITY modes respectively for
                                                                                each ::NV_OF_INIT_PARAMS::hintGridSize in a frame. */
    NV_OF_BOOL                      disableTemporalHints;            /**< [in]: To disable temporal hints per optical flow/stereo disparity execution.
                                                                                Temporal Hints is set by default.
                                                                                User can choose to disable temporal hints if there is no
                                                                                dependancy on previous optical flow execution. */
    uint32_t                        padding;                         /**< [in]: Padding.  Must be set to 0. */
    NvOFPrivDataHandle              hPrivData;                       /**< [in]: Optical flow private data handle. It is reserved field and should be set to NULL. */
} NV_OF_EXECUTE_INPUT_PARAMS;

/**
* \struct NV_OF_EXECUTE_OUTPUT_PARAMS
* Parameters which are received per frame for optical flow/stereo disparity execution.
*/
typedef struct _NV_OF_EXECUTE_OUTPUT_PARAMS
{
    NvOFGPUBufferHandle            outputBuffer;                     /**< [in]: Specifies the pointer to optical flow or stereo disparity buffer handle.
                                                                                ::outputBuffer will be populated with optical flow in
                                                                                ::NV_OF_FLOW_VECTOR format or stereo disparity in 
                                                                                ::NV_OF_STEREO_DISPARITY format for each 
                                                                                ::NV_OF_VECTOR_GRID_SIZE::outGridSize in a frame.*/
    NvOFGPUBufferHandle            outputCostBuffer;                 /**< [in]: Specifies the pointer to output cost calculation buffer handle. */
    NvOFPrivDataHandle             hPrivData;                        /**< [in]: Optical flow private data handle. It is reserved field and should be set to NULL. */
} NV_OF_EXECUTE_OUTPUT_PARAMS;

/**
* \brief Initialize NVIDIA Video Optical Flow Interface and validates input params.
*
* Initializes NVIDIA Video Optical Flow Interface and validates input params.
* It also initializes NVIDIA Video Optical Flow driver with the init value passed in ::NV_OF_INIT_PARAMS
* structure.
*
* \param [in] hOf
*   Object of ::NvOFHandle type.
* \param [in] initParams
*   Pointer to the ::NV_OF_INIT_PARAMS structure.
*
* \return
* ::NV_OF_SUCCESS \n
* ::NV_OF_ERR_INVALID_PTR \n
* ::NV_OF_ERR_UNSUPPORTED_DEVICE \n
* ::NV_OF_ERR_DEVICE_DOES_NOT_EXIST \n
* ::NV_OF_ERR_UNSUPPORTED_PARAM \n
* ::NV_OF_ERR_OUT_OF_MEMORY \n
* ::NV_OF_ERR_INVALID_PARAM \n
* ::NV_OF_ERR_INVALID_VERSION \n
* ::NV_OF_ERR_OF_NOT_INITIALIZED \n
* ::NV_OF_ERR_GENERIC \n
*/
typedef NV_OF_STATUS(NVOFAPI* PFNNVOFINIT) (NvOFHandle hOf, const NV_OF_INIT_PARAMS *initParams);

/**
* \brief Kick off computation of optical flow between input and reference frame.
*
* This is asynchronous function call which kicks off computation of optical flow or stereo disparity
* between ::NV_OF_EXECUTE_INPUT_PARAMS::inputFrame and ::NV_OF_EXECUTE_INPUT_PARAMS::referenceFrame and returns
* after submitting  execute paramaters to optical flow engine. 
* ::NV_OF_EXECUTE_OUTPUT_PARAMS::outputBuffer will be populated with optical flow or stereo disparity
* based on ::NV_OF_INIT_PARAMS:mode is NV_OF_MODE_OPTICALFLOW or NV_OF_MODE_STEREODISPARITY respectively.
*
* \param [in] hOf
*   Object of ::NvOFHandle type.
* \param [in] executeInParams
*   pointer to the ::NV_OF_EXECUTE_INPUT_PARAMS structure.
* \param [out] executeOutParams
*   pointer to the ::NV_OF_EXECUTE_OUTPUT_PARAMS structure.
*
* \return
* ::NV_OF_SUCCESS \n
* ::NV_OF_ERR_INVALID_PTR \n
* ::NV_OF_ERR_INVALID_DEVICE \n
* ::NV_OF_ERR_DEVICE_DOES_NOT_EXIST \n
* ::NV_OF_ERR_UNSUPPORTED_PARAM \n
* ::NV_OF_ERR_OUT_OF_MEMORY \n
* ::NV_OF_ERR_INVALID_PARAM \n
* ::NV_OF_ERR_INVALID_VERSION \n
* ::NV_OF_ERR_OF_NOT_INITIALIZED \n
* ::NV_OF_ERR_GENERIC \n
*/
typedef NV_OF_STATUS(NVOFAPI* PFNNVOFEXECUTE) (NvOFHandle hOf, const NV_OF_EXECUTE_INPUT_PARAMS *executeInParams, NV_OF_EXECUTE_OUTPUT_PARAMS *executeOutParams);

/**
* \brief Release optical flow API and driver resources.
*
* Releases resources and waits until all resources are gracefully released.
*
*  \param [in] hOf
*   Object of ::NvOFHandle type.
*
* \return
* ::NV_OF_SUCCESS \n
* ::NV_OF_ERR_INVALID_PTR \n
* ::NV_OF_ERR_DEVICE_DOES_NOT_EXIST \n
* ::NV_OF_ERR_OF_NOT_INITIALIZED \n
* ::NV_OF_ERR_GENERIC \n
*/
typedef NV_OF_STATUS(NVOFAPI* PFNNVOFDESTROY) (NvOFHandle hOf);

/**
* \brief Populate error buffer with the description of last failure.
*
* Populates lastError[] with the description of last failure.
*
* \param [in] hOf
*   Object of ::NvOFHandle type.
* \param [in/out] lastError
*   lastError is a char array, minimum expected size of lastError[] is MIN_ERROR_STRING_SIZE characters.
*   After execution of this function call, lastError[] is populated with error string.
* \param [in/out] As an input parameter, "size" indicates the size of the array provided by the client.
*   After execution of this function call, "size" field indicates the number of characters written into
*   "lastError" excluding null character.
* \return
* ::NV_OF_SUCCESS \n
* ::NV_OF_ERR_INVALID_PTR \n
* ::NV_OF_ERR_DEVICE_DOES_NOT_EXIST \n
* ::NV_OF_ERR_OF_NOT_INITIALIZED \n
* ::NV_OF_ERR_GENERIC \n
*/
typedef NV_OF_STATUS(NVOFAPI* PFNNVOFGETLASTERROR) (NvOFHandle hOf, char lastError[], uint32_t *size);

/**
* \brief Populate capability array for specified ::NV_OF_CAPS value.
* This is to be called in two stages.
* It returns the number of capability values for specified ::NV_OF_CAPS value when
* queried with "capsVal" set to NULL.
* It populates capsVal array with capability values for specified ::NV_OF_CAPS value
* when queried with "capsVal" set to non-NULL value.
*
*  \param [in] hOf
*   Object of ::NvOFHandle type.
*  \param [in] capsParam
*   object of ::NV_OF_CAPS type.
*  \param [out] capsVal
*   Pointer to uint32_t, minimum expected size of capsVal is the "size" returned by the this function call
*   queried with "capsVal" set to NULL.
* \param [out] size
*   Pointer to uint32_t, which stores size of populated capsVal.
*
* \return
* ::NV_OF_SUCCESS \n
* ::NV_OF_ERR_INVALID_PTR \n
* ::NV_OF_ERR_DEVICE_DOES_NOT_EXIST \n
* ::NV_OF_ERR_OF_NOT_INITIALIZED \n
* ::NV_OF_ERR_GENERIC \n
*/
typedef NV_OF_STATUS(NVOFAPI* PFNNVOFGETCAPS) (NvOFHandle hOf, NV_OF_CAPS capsParam, uint32_t *capsVal, uint32_t *size);

/**
* \brief Get the largest API version supported by the driver.
*
* This function can be used by clients to determine if the driver supports
* the API header the application was compiled with.
*
* \param [out] version
*   Pointer to the requested value. The 4 least significant bits in the returned
*   indicate the minor version and the rest of the bits indicate the major
*   version of the largest supported version.
*
* \return
* ::NV_OF_SUCCESS \n
* ::NV_OF_ERR_INVALID_PTR \n
*/
NV_OF_STATUS NVOFAPI NvOFGetMaxSupportedApiVersion(uint32_t* version);

#if defined(__cplusplus)
}
#endif /* __cplusplus */

#endif

#endif
