//CVG_LicenseBegin==============================================================
//
// Copyright@ GET 2005 (Groupe des Ecoles de Telecom)
// http://www.get-telecom.fr/
//
// This software is a GPU accelerated library for computer-vision. It
// supports an OPENCV-like extensible interface for easily porting OPENCV
// applications.
//
// Contacts:
// GpuCV core team: gpucv@picoforge.int-evry.fr
// GpuCV developers newsgroup: 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 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
// license as circulated by CEA, CNRS and INRIA at the following URL
// "http://www.cecill.info".
//
//================================================================CVG_LicenseEnd
#ifndef __GPUCV_DataDsc_CUDA_Array_H
#define __GPUCV_DataDsc_CUDA_Array_H
#include <GPUCVCuda/DataDsc_CUDA_Base.h>
#if _GPUCV_COMPILE_CUDA
#include <GPUCVTexture/Texture.h>
/** \brief DataDsc_CUDA_Array is the base class to describe CUDA array objects.
* \author Yannick Allusse
* \version CUDA 1.1 and GpuCV 4.1 rev 261
*/
class _GPUCV_CUDA_EXPORT DataDsc_CUDA_Array
:public DataDsc_CUDA_Base
{
protected:
size_t m_pitch; //!< See cudaMallocPitch().
cudaChannelFormatDesc * m_textureChannelDesc;
public:
/** \brief Default constructor. */
_GPUCV_CUDA_INLINE
DataDsc_CUDA_Array(void);
/** \brief Default destructor. */
_GPUCV_CUDA_INLINE virtual
~DataDsc_CUDA_Array(void);
/** \brief Redefinition of exception logging function */
virtual std::string LogException(void);
//Redefinition of data parameters manipulation
//Redefinition of data manipulation
_GPUCV_CUDA_INLINE virtual void Free();
//Redefinition of DataDsc_Base interaction with other objects
//access format, parameter are OpenGL enum format descriptor.
virtual bool CopyTo(DataDsc_Base* _destination, bool _datatransfer=true);
virtual bool CopyFrom(DataDsc_Base* _source, bool _datatransfer=true);
virtual DataDsc_Base * Clone(DataDsc_CUDA_Array * _src, bool _datatransfer=true);
virtual DataDsc_Base * CloneToNew(bool _datatransfer=true);
virtual std::ostringstream & operator << (std::ostringstream & _stream)const;
void PostProcessUpdate(void);
void PreProcessUpdate(void);
//local functions:
_GPUCV_CUDA_INLINE
void _SetCudaChannelFormatDesc(cudaChannelFormatDesc * _channelDesc);
_GPUCV_CUDA_INLINE
cudaChannelFormatDesc* _GetCudaChannelFormatDesc(void);
/** \brief Allocate a CUDA device buffer.
\param _datatype => Type of data to allocate using CUDA type descriptors [CU_AD_FORMAT_UNSIGNED_INT8 | CU_AD_FORMAT_UNSIGNED_INT16 | CU_AD_FORMAT_FLOAT ...]
*/
void _AllocateDevice(unsigned int _datatype);
/** \brief Create a cuda channel descriptor.
\param TType => Type of data to allocate using "C" data type [char|uchar|int|float...]
\return A new channel descriptor.
*/
template <typename TType>
cudaChannelFormatDesc CreateCudaChannelDesc()
{
char x, y, z, w;
x=y=z=w=0;
enum cudaChannelFormatKind ChannelFormat;
char ChannelSize = sizeof(TType)*8;
switch(m_nChannels)
{
case 4:
case 3: w = ChannelSize;
z = ChannelSize;
case 2: y = ChannelSize;
case 1: x = ChannelSize;break;
default:
CLASS_ASSERT(0, "Unknown switch value(channel number).");
}
if(typeid(TType) == typeid(char) || typeid(TType) == typeid(int))
ChannelFormat = cudaChannelFormatKindSigned;
else if(typeid(TType) == typeid(unsigned char) || typeid(TType) == typeid(unsigned int))
ChannelFormat = cudaChannelFormatKindUnsigned;
else if(typeid(TType) == typeid(double) || typeid(TType) == typeid(float))
ChannelFormat = cudaChannelFormatKindFloat;
else
{
CLASS_ASSERT(0, "Unknown switch value(Channel format).");
}
return gcudaCreateChannelDesc(x, y, z, w, ChannelFormat);
}
/** \brief Allocate a CUDA device buffer(template function).
\param TType => Type of data to allocate using "C" data type [char|uchar|int|float...]
\return True if data allocation was succesfull.
*/
template <typename TType>
bool _AllocateDataPtr(void)
{
CLASS_FCT_SET_NAME_TPL(TType,"_AllocateDataPtr");
#if _GCU_DEBUG_MEMORY_ALLOC
unsigned int TotalMem=0;
unsigned int FreeMem=0;
cuMemGetInfo(&FreeMem,&TotalMem);
CLASS_NOTICE("");
GPUCV_NOTICE("BEFORE=>Cuda free memory:" << FreeMem << "(" << (double)FreeMem/TotalMem*100. <<"%)");
if(FreeMem==0 || TotalMem==0)
{
GPUCV_NOTICE("We don't have free memory..??");
}
#endif
m_memSize = GetDataSize();
// texture<unsigned char, 1,cudaReadModeElementType> texTest;
//CreateCudaChannelDesc<TType>();//8,0,0,0,cudaChannelFormatKindUnsigned);//8,8,8,,cudaChannelFormatKindUnsigned);
//cudaCreateChannelDesc<
if(!_GetCudaChannelFormatDesc())
{
//m_textureChannelDesc = &gcudaCreateChannelDesc(8, 8, 8, 8, cudaChannelFormatKindUnsigned);
_SetCudaChannelFormatDesc(&CreateCudaChannelDesc<TType>());//m_textureChannelDesc = &gcudaCreateChannelDesc(8, 8, 8, 8, cudaChannelFormatKindUnsigned);
}
#if _GPUCV_CUDA_USE_SINGLE_CHANNEL_IMG
CLASS_DEBUG("cudaMallocArray(m_textureArrayPtr, desc,"<< _GetWidth()*_GetNChannels() <<","<< _GetHeight()<<")");
gcudaMallocArray(&m_data.m_textureArrayPtr, m_textureChannelDesc, _GetWidth()*_GetNChannels(), _GetHeight());
//cudaMallocPitch((&m_data.m_textureArrayPtr
#else
CLASS_DEBUG("cudaMallocArray(m_textureArrayPtr, desc,"<< _GetWidth() <<","<< _GetHeight()<<")");
gcudaMallocArray(&m_data.m_textureArrayPtr, m_textureChannelDesc, _GetWidth(), _GetHeight());
#endif
//retrieve real pointer to CUDA dest, the previous one was a local object that will be destroyed when leaving the function.
cudaGetChannelDesc(m_textureChannelDesc, m_data.m_textureArrayPtr);
gcudaCheckError("Error allocating m_textureArrayPtr.");
CLASS_ASSERT(m_data.m_textureArrayPtr, "_AllocateDataPtr()=> Could not allocate pointer");
CLASS_DEBUG("cudaMemset(m_textureArrayPtr, 0,"<< m_memSize<<")");
#if _DEBUG
gcudaMemset(m_data.m_textureArrayPtr, 0, m_memSize);
#endif
gcudaCheckError("DataDsc_CUDA_Array::_AllocateDataPtr() execution failed\n");
//how to get error code from CUDA..?
#if _GCU_DEBUG_MEMORY_ALLOC
cuMemGetInfo(&FreeMem,&TotalMem);
CLASS_NOTICE("AFTER=>Cuda free memory: " << FreeMem << " (" << (double)FreeMem/TotalMem*100. <<"% )");
#endif
return true;
}
/** \brief Get CUDA memory pitch value.
\return CUDA memory pitch value.
*/
_GPUCV_CUDA_INLINE
size_t _GetPitch(void)const;
};
#endif//_GPUCV_COMPILE_CUDA
#endif//__GPUCV_DataDsc_CUDA_Array_H
|