Subversion

gpucv

[/] [experimental/] [opencl/] [src/] [lib/] [GPUCVOCL/] [gpucv_wrapper_c.cpp] - Rev 607

Compare with Previous - Blame


//CVG_LicenseBegin==============================================================
//
//	Copyright@ Institut TELECOM 2005
//		http://www.institut-telecom.fr/en_accueil.html
//
//	This software is a GPU accelerated library for computer-vision. It
//	supports an OPENCV-like extensible interface for easily porting OPENCV
//	applications.
//
//	Contacts :
//		patrick.horain@it-sudparis.eu
//		gpucv-developers@picoforge.int-evry.fr
//
//	Project's Home Page :
//		https://picoforge.int-evry.fr/cgi-bin/twiki/view/Gpucv/Web/WebHome
//
//	This software is governed by the CeCILL-B license under French law and
//	abiding by the rules of distribution of free software.  You can  use,
//	modify and/ or redistribute the software under the terms of the CeCILL-B
//	license as circulated by CEA, CNRS and INRIA at the following URL
//	"http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html".
//
//================================================================CVG_LicenseEnd
#include "StdAfx.h"
#include <GPUCV/include.h>
#include <GPUCVCuda/config.h>

#if _GPUCV_COMPILE_CUDA
#include <GPUCVCuda/DataDsc_CUDA_Buffer.h>
#include <GPUCVCuda/gpucv_wrapper_c.h>
#include <GPUCVCuda/GPU_NVIDIA_CUDA.h>

#include <cxcoreg/cxcoreg.h>
#include <highguig/highguig.h>

using namespace GCV;
//=================================================
GLuint gcuGetWidth(const CvArr * arr)
{
        return GetWidth(arr);
}
//=================================================
GLuint gcuGetHeight(const CvArr * arr)
{
        return GetHeight(arr);
}
//=================================================
GLuint gcuGetGLDepth(const CvArr * arr)
{
        return GetGLDepth(arr);
}
//=================================================
GLuint gcuGetCVDepth	(const CvArr * arr)
{
        return GetCVDepth(arr);
}
//=================================================
GLuint gcuGetnChannels(const CvArr * arr)
{
        return GetnChannels(arr);
}
//=================================================
GLuint gcuGetGLTypeSize	(unsigned int _depth)
{
        return GetGLTypeSize(_depth);
}
//=================================================
bool gcuGetDoubleSupport()
{
        GPU_NVIDIA_CUDA *cuda_gpu = dynamic_cast<GPU_NVIDIA_CUDA *>(GCV::ProcessingGPU());
        if(cuda_gpu)
                return cuda_gpu->IsDoubleSupported();
        return false;
}
//=================================================
cudaDeviceProp * gcuGetDeviceProperties()
{
        GPU_NVIDIA_CUDA *cuda_gpu = dynamic_cast<GPU_NVIDIA_CUDA *>(GCV::ProcessingGPU());
        if(cuda_gpu)
                return &cuda_gpu->GetCudaProperties();
        return NULL;//default is 16
}
//=================================================
/**
\bug FIXED: the local cache is not working properly cause an IplImage address can be reaffected by the OS to another IplImage, then it was looking for an non allocated CvgArr pointer.
*/
inline
CvgArr * GetCvgArr(void * _img)
{
        GCU_Assert(_img,"GetCvgArr()=>Empty obj");
#if 0
        static void * lastImg=NULL;
        static CvgArr * lastCvgImg=NULL;

        if(_img == lastImg)
                return lastCvgImg;
        else

        {
                lastCvgImg = dynamic_cast<CvgArr*>(GPUCV_GET_TEX(_img));
                if(lastCvgImg)
                        lastImg = _img;
                return lastCvgImg;
        }
#else
        return dynamic_cast<CvgArr*>(GPUCV_GET_TEX(_img));
#endif
}
//=================================================
#if _GPUCV_DEPRECATED
inline
DataDsc_CUDA_Base * GetCudaDesc(void * _img)
{
        static void * lastImg=NULL;
        static DataDsc_CUDA_Base * lastCudaDsc=NULL;
        GCU_Assert(_img,"GetCvgArr()=>Empty obj");

        if(_img == lastImg)
                return lastCudaDsc;
        else
        {
                CvgArr * cvgImg = GetCvgArr(_img);
                if(cvgImg)
                {
                        lastCudaDsc= cvgImg->GetDataDsc<DataDsc_CUDA_Base>();
                        lastImg = _img;
                        return lastCudaDsc;
                }
                else
                        return NULL;
        }
}
#endif
//=================================================
void* gcuPreProcess(void * _img, GCU_IO_TYPE _iotype, int _cudaMemoryType/*=0*/, cudaChannelFormatDesc* _channelDesc/*=NULL*/)
{
        GPUCV_FUNCNAME("gcu_PreProcess");

        //CvgArr * CurCvArr = dynamic_cast<CvgArr*>(GPUCV_GET_TEX(_img));
        CvgArr * CurCvArr = GetCvgArr(_img);

        if (!CurCvArr)
        {
                GPUCV_ERROR(GPUCV_GET_FCT_NAME() <<"=> Input obj not an OpenCV object");
                return NULL;
        }

        DataDsc_CUDA_Base * CudaImg=NULL;

        //we control data transfer
        bool Datatransfer = false;
        if(_iotype == GCU_OUTPUT)
        {//manage destination Textures ========================
                CurCvArr->PushSetOptions(DataContainer::DEST_IMG, true);
        }
        else
        {//manage sources Textures ========================
                CurCvArr->PushSetOptions(DataContainer::UBIQUITY, true);	//is used to preserve CPU image if we have cpu_return set
                CurCvArr->SetOption(DataContainer::DEST_IMG, false);
                Datatransfer = true;
        }

        //make sure image is on GPU
        if(_cudaMemoryType == CU_MEMORYTYPE_DEVICE)
        {
                CudaImg = CurCvArr->SetLocation<DataDsc_CUDA_Buffer>(Datatransfer);
                if(_channelDesc)
                        GPUCV_WARNING("_channelDsc is defined and memory type is CU_MEMORYTYPE_DEVICE, it should be CU_MEMORYTYPE_ARRAY");
        }
        else if(_cudaMemoryType = CU_MEMORYTYPE_ARRAY)
        {
                if(_channelDesc)
                        CurCvArr->GetDataDsc<DataDsc_CUDA_Array>()->_SetCudaChannelFormatDesc(_channelDesc);
                CudaImg = CurCvArr->SetLocation<DataDsc_CUDA_Array>(Datatransfer);
        }
        else
                GPUCV_ERROR("Unknown CUDA MEMORY TYPE:" << _cudaMemoryType);

        return CudaImg->_GetDataPtr();

}
//=================================================
bool gcuPostProcess(void * _img)
{
        GPUCV_FUNCNAME("gcu_PostProcess");

        //CvgArr * CurCvArr = dynamic_cast<CvgArr*>(GPUCV_GET_TEX(_img));
        CvgArr * CurCvArr = GetCvgArr(_img);

        if (!CurCvArr)
        {
                GPUCV_ERROR(GPUCV_GET_FCT_NAME() <<"=> Input obj not an OpenCV object");
                return false;
        }

        if(CurCvArr->GetOption(DataContainer::DEST_IMG))
        {//manage destination Textures ========================
                //	CurCvArr->PushSetOptions(DataContainer::DEST_IMG, true);

                if (CurCvArr->GetOption(DataContainer::CPU_RETURN))
                {
                        CurCvArr->SetLocation<DataDsc_CPU>(true);
                }
                CurCvArr->PopOptions();
                //destination is now considered as input texture...
                CurCvArr->SetOption(DataContainer::DEST_IMG, false);
                return true;
        }
        else
        {//manage sources Textures ========================
                //???if (CurCvArr->GetOption(DataContainer::CPU_RETURN))
                //???	CurCvArr->SetLocation<DataDsc_CPU>(true);
                CurCvArr->PopOptions();
                return true;
        }
}

//=================================================
size_t gcuGetPitch(void * _img)
{
        GPUCV_FUNCNAME("gcuGetPitch");

        //CvgArr * CurCvArr = dynamic_cast<CvgArr*>(GPUCV_GET_TEX(_img));
        CvgArr * CurCvArr = GetCvgArr(_img);

        if (!CurCvArr)
        {
                GPUCV_ERROR(GPUCV_GET_FCT_NAME() <<"=> Input obj not an OpenCV object");
                return NULL;
        }

        if(CurCvArr->FindDataDscID<DataDsc_CUDA_Buffer>()>=0)
        {
                DataDsc_CUDA_Buffer * CudaBuff= CurCvArr->GetDataDsc<DataDsc_CUDA_Buffer>();
                if(CudaBuff)
                        return CudaBuff->_GetPitch();
        }
        return 0;
}
//=================================================
void* gcuSyncToCPU(void * _img, bool _dataTransfer)
{
        GPUCV_FUNCNAME("gcuSyncToCPU");

        if(_img==NULL)
                return NULL;
        //CvgArr * CurCvArr = dynamic_cast<CvgArr*>(GPUCV_GET_TEX(_img));
        CvgArr * CurCvArr = GetCvgArr(_img);

        if (!CurCvArr)
        {
                GPUCV_ERROR(GPUCV_GET_FCT_NAME() <<"=> Input obj not an OpenCV object");
                return NULL;
        }

        DataDsc_CPU * CPUImg = CurCvArr->SetLocation<DataDsc_CPU>(_dataTransfer);
        return *CPUImg->_GetPixelsData();
}
//======================================
#if _GPUCV_DEPRECATED
void gcuSetReshapeObj(void * _img, GCU_IO_TYPE _iotype, int _cudaMemoryType, int _newChannels)
{
        GPUCV_FUNCNAME("gcuSetReshapeObj");

        if(_img==NULL)
                return;
        //CvgArr * CurCvArr = dynamic_cast<CvgArr*>(GPUCV_GET_TEX(_img));
        CvgArr * CurCvArr = GetCvgArr(_img);

        if (!CurCvArr)
        {
                GPUCV_ERROR(GPUCV_GET_FCT_NAME() <<"=> Input obj not an OpenCV object");
                return;
        }

        DataDsc_CUDA_Base * CudaImg=NULL;
        bool DataTransfer = (_iotype==GCU_OUTPUT)?false:true;

        //make sure image is on GPU
        if(_cudaMemoryType == CU_MEMORYTYPE_DEVICE)
        {
                CudaImg = CurCvArr->SetLocation<DataDsc_CUDA_Buffer>(DataTransfer);
        }
        else if(_cudaMemoryType = CU_MEMORYTYPE_ARRAY)
        {
                CudaImg = CurCvArr->SetLocation<DataDsc_CUDA_Array>(DataTransfer);
        }
        else
                GPUCV_ERROR("Unknown CUDA MEMORY TYPE:" << _cudaMemoryType);

        CudaImg->SetReshape(_newChannels);
}
//=================================================
void gcuUnsetReshapeObj(void * _img,int _cudaMemoryType)
{
        GPUCV_FUNCNAME("gcuUnsetReshapeObj");
        if(_img==NULL)
                return;

        //CvgArr * CurCvArr = dynamic_cast<CvgArr*>(GPUCV_GET_TEX(_img));
        CvgArr * CurCvArr = GetCvgArr(_img);

        if (!CurCvArr)
        {
                GPUCV_ERROR(GPUCV_GET_FCT_NAME() <<"=> Input obj not an OpenCV object");
                return;
        }

        DataDsc_CUDA_Base * CudaImg=NULL;

        //get DataDesc
        if(_cudaMemoryType == CU_MEMORYTYPE_DEVICE)
        {
                CudaImg = CurCvArr->GetDataDsc<DataDsc_CUDA_Buffer>();
        }
        else if(_cudaMemoryType = CU_MEMORYTYPE_ARRAY)
        {
                CudaImg = CurCvArr->GetDataDsc<DataDsc_CUDA_Array>();
        }
        else
                GPUCV_ERROR("Unknown CUDA MEMORY TYPE:" << _cudaMemoryType);

        CudaImg->UnsetReshape();
}
#endif//DEPRECATED
//=================================================
bool gcuGetDataDscSize(void * _img,int _cudaMemoryType, unsigned int & width, unsigned int &height)
{
        GPUCV_FUNCNAME("gcuDataDscSize");
        //CvSize Size;
        //Size.width=Size.height=0;
        if(_img==NULL)
        {
                return false;
        }

        //CvgArr * CurCvArr = dynamic_cast<CvgArr*>(GPUCV_GET_TEX(_img));
        CvgArr * CurCvArr = GetCvgArr(_img);

        if (!CurCvArr)
        {
                GPUCV_ERROR(GPUCV_GET_FCT_NAME() <<"=> Input obj not an OpenCV object");
                return false;
        }

        DataDsc_CUDA_Base * CudaImg=NULL;

        //make sure image is on GPU
        if(_cudaMemoryType == CU_MEMORYTYPE_DEVICE)
        {
                CudaImg = CurCvArr->GetDataDsc<DataDsc_CUDA_Buffer>();
        }
        else if(_cudaMemoryType = CU_MEMORYTYPE_ARRAY)
        {
                CudaImg = CurCvArr->GetDataDsc<DataDsc_CUDA_Array>();
        }
        else
        {
                GPUCV_ERROR("Unknown CUDA MEMORY TYPE:" << _cudaMemoryType);
                return false;
        }

        width = CudaImg->_GetWidth();
        height = CudaImg->_GetHeight();
        return true;
}
//=================================================
#if _GPUCV_DEPRECATED
bool FindBestLoad(unsigned int _size, unsigned int & _blockNbr, unsigned int & _ThreadNbr, unsigned int & _ThreadWidth)
{
        unsigned int CurProcSize = _blockNbr*_ThreadNbr*_ThreadWidth;
        if(_size == CurProcSize)
        {//well, it fits...see optimisations later
                return true;
        }

        //make sure current value are not too high
        while(_size < _ThreadWidth)
        {
                _ThreadWidth -= 16;
                GPUCV_ERROR("Reduce _ThreadWidth to "<< _ThreadWidth);
                if(_ThreadWidth < 1)
                {
                        _ThreadWidth = 1;
                        break;
                }
        }

        //========================================
        float fCoef = 0;
        int iCoef = 0;

        if(IS_MULTIPLE_OF(_size,2))
        {
                fCoef = _size/_ThreadWidth;
                if(IS_INTEGER(fCoef))
                {
                        iCoef = fCoef;

                        if(IS_MULTIPLE_OF(iCoef,2))
                        {//we can use a simple *2 |/2 mechanism
                                //dispatch the load on ThreadNbr and BlockNbr
                                for(int i = _ThreadNbr; i > 0; i>>=1)
                                {
                                        if (IS_MULTIPLE_OF(iCoef,i))
                                        {
                                                _ThreadNbr = i;
                                                if(_blockNbr>=iCoef/_ThreadNbr)
                                                {
                                                        _blockNbr = iCoef/_ThreadNbr;
                                                        return true;
                                                }
                                                else
                                                {
                                                        GPUCV_ERROR("Block Nbr exceed maximum block number defined");
                                                        return false;
                                                }
                                        }
                                }
                        }
                }
                else
                {//find something else...
                }
        }
        GPUCV_ERROR("Could not find best values");
        return false;


        //using the given parameter we try to adjust using the following rules.
        // 1- if _ThreadWidth == 1, we don't change it.
        // 2- _ThreadNbr should be multiple of 2, and inferior to 512(later we may consider the 2 dimensions).
        // 3- _blockNbr is not really limited

        /*
        if(Coef < 1)
        {//we increase values
        Coef = CurProcSize_size/
        }
        */
}
#endif// _GPUCV_DEPRECATED
//=======================================
void gcuShowImage(char* Name, unsigned int width, unsigned int height, unsigned int depth, unsigned int channels, void * _device_data, int _pixelSize, float extra_scale)
{
//#if defined (_LINUX) || defined (_MACOS)
        IplImage * TempImge = cvgCreateImage(cvSize(width, height), depth, channels);
        //	cvCreateData(TempImge);
        gcudaThreadSynchronize();
        gcudaMemCopyDeviceToHost(TempImge->imageData, _device_data, width*height*channels*_pixelSize);
        gcudaThreadSynchronize();
        if(extra_scale!=1.)
                cvScale(TempImge, TempImge, extra_scale);
        cvNamedWindow(Name, 1);
        cvgShowImage(Name, TempImge);
        cvWaitKey(0);
        cvDestroyWindow(Name);
        cvgReleaseImage(&TempImge);
//#else
//	GPUCV_NOTICE("gcuShowImage(): Fonction no supported under windows");
//#endif
}
//=======================================
#endif//#if _GPUCV_COMPILE_CUDA

Powered by WebSVN v1.61