blob: ca8e0de6137e1763dd5db7321b339563ccb97b4b [file] [log] [blame]
/*
* Copyright (c) 2013-2017 The Khronos Group Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <VX/vx.h>
#include "vx_lib_testmodule.h"
/*! An internal definition of the order of the parameters to the function.
* This list must match the parameter list in the function and in the
* publish kernel list.
* \ingroup group_testmodule_kernel
*/
typedef enum _test_params_e {
TESTMODULE_PARAM_INPUT = 0,
TESTMODULE_PARAM_VALUE,
TESTMODULE_PARAM_OUTPUT,
TESTMODULE_PARAM_TEMP
} test_params_e;
/*! \brief An example parameter validator.
* \param [in] node The handle to the node.
* \param [in] parameters The array of parameters to be validated.
* \param [in] num Number of parameters to be validated.
* \param [out] metas The array of metadata used to check output parameters only.
* \return A \ref vx_status_e enumeration.
* \ingroup group_testmodule_kernel
*/
vx_status VX_CALLBACK TestModuleValidator(vx_node node, const vx_reference parameters[], vx_uint32 num, vx_meta_format metas[])
{
vx_uint32 i;
if (num != (TESTMODULE_PARAM_TEMP + 1))
return VX_ERROR_INVALID_PARAMETERS;
for (i = 0u; i < num; i++)
{
if (!parameters[i])
return VX_ERROR_INVALID_REFERENCE;
switch (i)
{
case TESTMODULE_PARAM_INPUT:
{
vx_df_image df_image = 0;
if (vxQueryImage((vx_image)parameters[i], VX_IMAGE_FORMAT, &df_image, sizeof(df_image)) != VX_SUCCESS)
return VX_ERROR_INVALID_PARAMETERS;
if (df_image != VX_DF_IMAGE_U8)
return VX_ERROR_INVALID_VALUE;
} break;
case TESTMODULE_PARAM_VALUE:
{
vx_enum type = 0;
vx_int32 value = 0;
if (vxQueryScalar((vx_scalar)parameters[i], VX_SCALAR_TYPE, &type, sizeof(type)) != VX_SUCCESS)
return VX_ERROR_INVALID_PARAMETERS;
if (type != VX_TYPE_INT32 ||
vxCopyScalar((vx_scalar)parameters[i], &value, VX_READ_ONLY, VX_MEMORY_TYPE_HOST) != VX_SUCCESS)
return VX_ERROR_INVALID_PARAMETERS;
if (TESTMODULE_VALUE_MIN >= value || value >= TESTMODULE_VALUE_MAX)
return VX_ERROR_INVALID_VALUE;
} break;
case TESTMODULE_PARAM_OUTPUT:
{
vx_image input = (vx_image)parameters[TESTMODULE_PARAM_INPUT];
vx_uint32 width = 0, height = 0;
vx_df_image format = VX_DF_IMAGE_VIRT;
if (!metas[i])
return VX_ERROR_INVALID_REFERENCE;
if (vxQueryImage(input, VX_IMAGE_FORMAT, &format, sizeof(format)) != VX_SUCCESS ||
vxQueryImage(input, VX_IMAGE_WIDTH, &width, sizeof(width)) != VX_SUCCESS ||
vxQueryImage(input, VX_IMAGE_HEIGHT, &height, sizeof(height)) != VX_SUCCESS)
return VX_ERROR_INVALID_PARAMETERS;
if (vxSetMetaFormatAttribute(metas[i], VX_IMAGE_WIDTH, &width, sizeof(width)) != VX_SUCCESS ||
vxSetMetaFormatAttribute(metas[i], VX_IMAGE_HEIGHT, &height, sizeof(height)) != VX_SUCCESS ||
vxSetMetaFormatAttribute(metas[i], VX_IMAGE_FORMAT, &format, sizeof(format)))
return VX_ERROR_INVALID_VALUE;
} break;
case TESTMODULE_PARAM_TEMP:
{
vx_size num_items = 0;
if (vxQueryArray((vx_array)parameters[i], VX_ARRAY_NUMITEMS, &num_items, sizeof(num_items)) != VX_SUCCESS)
return VX_ERROR_INVALID_PARAMETERS;
if (num_items < TESTMODULE_TEMP_NUMITEMS)
return VX_ERROR_INVALID_DIMENSION;
} break;
default:
return VX_ERROR_INVALID_PARAMETERS;
}
}
return VX_SUCCESS;
}
/*!
* \brief The private kernel function for TestModule.
* \note This is not called directly by users.
* \param [in] node The handle to the node this kernel is instanced into.
* \param [in] parameters The array of \ref vx_reference references.
* \param [in] num The number of parameters in the array.
* functions.
* \return A \ref vx_status_e enumeration.
* \retval VX_SUCCESS Successful return.
* \retval VX_ERROR_INVALID_PARAMETER The input or output image were
* of the incorrect dimensions.
* \ingroup group_testmodule_kernel
*/
vx_status VX_CALLBACK TestModuleKernel(vx_node node, const vx_reference *parameters, vx_uint32 num)
{
vx_status status = VX_ERROR_INVALID_PARAMETERS;
if (num == 4)
{
vx_image input = (vx_image)parameters[0];
vx_scalar scalar = (vx_scalar)parameters[1];
vx_image output = (vx_image)parameters[2];
vx_array temp = (vx_array)parameters[3];
void *buf, *in = NULL, *out = NULL;
vx_uint32 y, x;
vx_int32 value = 0;
vx_imagepatch_addressing_t addr1, addr2;
vx_rectangle_t rect;
vx_enum item_type = VX_TYPE_INVALID;
vx_size num_items = 0, capacity = 0;
vx_size stride = 0;
vx_map_id map_id_input, map_id_output, map_id_array;
status = VX_SUCCESS;
status |= vxCopyScalar(scalar, &value, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);
status |= vxGetValidRegionImage(input, &rect);
status |= vxMapImagePatch(input, &rect, 0, &map_id_input, &addr1, &in, VX_READ_ONLY, VX_MEMORY_TYPE_HOST, VX_NOGAP_X);
status |= vxMapImagePatch(output, &rect, 0, &map_id_output, &addr2, &out, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST, VX_NOGAP_X);
status |= vxQueryArray(temp, VX_ARRAY_ITEMTYPE, &item_type, sizeof(item_type));
status |= vxQueryArray(temp, VX_ARRAY_NUMITEMS, &num_items, sizeof(num_items));
status |= vxQueryArray(temp, VX_ARRAY_CAPACITY, &capacity, sizeof(capacity));
status |= vxMapArrayRange(temp, 0, num_items, &map_id_array, &stride, &buf, VX_READ_AND_WRITE, VX_MEMORY_TYPE_HOST, 0);
for (y = 0; y < addr1.dim_y; y+=addr1.step_y)
{
for (x = 0; x < addr1.dim_x; x+=addr1.step_x)
{
// do some operation...
}
}
status |= vxUnmapArrayRange(temp, map_id_array);
status |= vxUnmapImagePatch(output, map_id_output);
status |= vxUnmapImagePatch(input, map_id_input);
}
return status;
}
/*! \brief An initializer function.
* \param [in] node The handle to the node this kernel is instanced into.
* \param [in] parameters The array of \ref vx_reference references.
* \param [in] num The number of parameters in the array.
* functions.
* \return A \ref vx_status_e enumeration.
* \retval VX_SUCCESS Successful return.
* \retval VX_ERROR_INVALID_PARAMETER The input or output image were
* of the incorrect dimensions.
* \ingroup group_testmodule_kernel
*/
vx_status VX_CALLBACK TestModuleInitialize(vx_node node, const vx_reference *parameters, vx_uint32 num)
{
/* TestModule requires no initialization of memory or resources */
return VX_SUCCESS;
}
/*! \brief A deinitializer function.
* \param [in] node The handle to the node this kernel is instanced into.
* \param [in] parameters The array of \ref vx_reference references.
* \param [in] num The number of parameters in the array.
* functions.
* \return A \ref vx_status_e enumeration.
* \retval VX_SUCCESS Successful return.
* \retval VX_ERROR_INVALID_PARAMETER The input or output image were
* of the incorrect dimensions.
* \ingroup group_testmodule_kernel
*/
vx_status VX_CALLBACK TestModuleDeinitialize(vx_node node, const vx_reference *parameters, vx_uint32 num)
{
/* TestModule requires no de-initialization of memory or resources */
return VX_SUCCESS;
}
//**********************************************************************
// PUBLIC FUNCTION
//**********************************************************************
/*! \brief The entry point into this module to add the extensions to OpenVX.
* \param [in] context The handle to the implementation context.
* \return A \ref vx_status_e enumeration. Returns errors if some or all kernels were not added
* correctly.
* \note This follows the function pointer definition of a \ref vx_publish_kernels_f
* and uses the predefined name for the entry point, "vxPublishKernels".
* \ingroup group_testmodule_kernel
*/
/*VX_API_ENTRY*/ vx_status VX_API_CALL vxPublishKernels(vx_context context)
{
vx_status status = VX_SUCCESS;
vx_kernel kernel = vxAddUserKernel(context,
"org.khronos.test.testmodule",
VX_KERNEL_KHR_TESTMODULE,
TestModuleKernel,
4,
TestModuleValidator,
TestModuleInitialize,
TestModuleDeinitialize);
if (kernel)
{
vx_size size = TESTMODULE_DATA_AREA;
status = vxAddParameterToKernel(kernel, 0, VX_INPUT, VX_TYPE_IMAGE, VX_PARAMETER_STATE_REQUIRED);
if (status != VX_SUCCESS) goto exit;
status = vxAddParameterToKernel(kernel, 1, VX_INPUT, VX_TYPE_SCALAR, VX_PARAMETER_STATE_REQUIRED);
if (status != VX_SUCCESS) goto exit;
status = vxAddParameterToKernel(kernel, 2, VX_OUTPUT, VX_TYPE_IMAGE, VX_PARAMETER_STATE_REQUIRED);
if (status != VX_SUCCESS) goto exit;
status = vxAddParameterToKernel(kernel, 3, VX_OUTPUT, VX_TYPE_ARRAY, VX_PARAMETER_STATE_REQUIRED);
if (status != VX_SUCCESS) goto exit;
status = vxSetKernelAttribute(kernel, VX_KERNEL_LOCAL_DATA_SIZE, &size, sizeof(size));
if (status != VX_SUCCESS) goto exit;
status = vxFinalizeKernel(kernel);
if (status != VX_SUCCESS) goto exit;
}
exit:
if (status != VX_SUCCESS) {
vxRemoveKernel(kernel);
}
return status;
}
/*! \brief The destructor to remove a user loaded module from OpenVX.
* \param [in] context The handle to the implementation context.
* \return A \ref vx_status_e enumeration. Returns errors if some or all kernels were not added
* correctly.
* \note This follows the function pointer definition of a \ref vx_unpublish_kernels_f
* and uses the predefined name for the entry point, "vxUnpublishKernels".
* \ingroup group_testmodule_kernel
*/
/*VX_API_ENTRY*/ vx_status VX_API_CALL vxUnpublishKernels(vx_context context)
{
vx_status status = VX_SUCCESS;
vx_kernel kernel = vxGetKernelByName(context, "org.khronos.test.testmodule");
vx_kernel kernelcpy = kernel;
if (kernel)
{
status = vxReleaseKernel(&kernelcpy);
if (status == VX_SUCCESS)
{
status = vxRemoveKernel(kernel);
}
}
return status;
}