Reputation: 23
I'm currently developing a project where I do a lot of video processing. The project uses C++, openGL and glsl. Recently I added some CUDA routines to it, to do some more advanced image processing work.I managed to use the openGL textures in cuda, however now I'm trying to use some of the cuda's npp functions with the openGL texture as input (without succes).
For example I want to calculate the mean and std. deviation of a pre-processed input openGL texture:
//I first connect the cudaGraphicsResource to a cudaArray
//cudaGraphicsResource_t inputImage is input passed from openGL framework
cudaGraphicsMapResources(1,&inputImage);
cudaArray* inputImgArray = NULL;
cudaGraphicsSubResourceGetMappedArray(&inputArray, inputImage,0,0);
//Next I do some preparationwork and cast the cudaArray to a Npp8u* and give
//it as an input source imagebuffer to the npp routine.
NppiSize roi={imgwidth, imgheight};
int bufferSize = 0;
nppiMeanStdDev8uC1RGetBufferHostSize(roi,bufferSize);
double mean = 0;
double stdDev = 0;
Npp8u* scratch = nppsMalloc_8f(bufferSize);
int stepSize = imgWidth * sizeof(unsigned char);
NppStatus status = nppiMean_stdDev_8u_C1R((Npp8u*)inputImgArray, stepSize, roi, scratch,&mean,&stdDev);
//cleanup
nppsFree(bufferSize);
cudaGraphicsUnmapresources(1,&inputImage);
The nppiMean_stdDev_8u_C1R function always returns with the error code: NPP_MEMCPY_ERROR. I looked everywhere in the manuals, but I could not find if this was the correct way to work with NPP and opengl textures. I could not find anything of it on the internet either. I can't believe that I am the first one, who is trying to do these kind of things with NPP. Maybe I just missed a major chapter in an important document :-).
Upvotes: 2
Views: 2162
Reputation: 27849
You need to pass device pointers to NPP, rather than CUDA arrays. So in your case, I think you want to use cudaGraphicsResourceGetMappedPointer
instead of cudaGraphicsSubResourceGetMappedArray
.
For example: (Disclaimer: This code was written in browser, untested, unverified.)
//I first connect the cudaGraphicsResource to a cudaArray
//cudaGraphicsResource_t inputImage is input passed from openGL framework
cudaGraphicsMapResources(1,&inputImage);
unsigned char* inputPtr = NULL; // to hold device pointer to input image
size_t inputSize;
cudaGraphicsResourceGetMappedPointer((void**)&inputPtr, &inputSize, inputImage);
//Next I do some preparation work and cast the device pointer to a Npp8u* and give
//it as an input source imagebuffer to the npp routine.
NppiSize roi={imgwidth, imgheight};
int bufferSize = 0;
nppiMeanStdDev8uC1RGetBufferHostSize(roi, &bufferSize); // note & missing from original!
double mean = 0;
double stdDev = 0;
Npp8u* scratch = nppsMalloc_8f(bufferSize);
int stepSize = imgWidth * sizeof(unsigned char);
NppStatus status = nppiMean_stdDev_8u_C1R((Npp8u*)inputPtr, stepSize, roi, scratch, &mean, &stdDev);
//cleanup
nppsFree(bufferSize);
cudaGraphicsUnmapresources(1,&inputImage);
Upvotes: 2