Does CUDA support 24bit float ? Try to use openGL depthbuffer in CUDA

Hi, is there any way to use a 24bit float texture in CUDA ?
I want to use the depthbuffer in my CUDA-process, but my graphicscard does not support 32bit depth-buffer, or I am to stupid to set it in glut( I tryed glutInitDisplayString(“depth=32”); but this doesnet change anything).

Does some one know, how to solve this problem ?

Thank you.

Many regards,

d’Matthias

The depth buffer isn’t 24-bit float, it’s 24 bit integer. You should be able to read it into a 32-bit integer array (PBO) using glReadPixels and read from CUDA.

Ok, but isn’t it very slow to use glReadPixels for accessing the depthbuffer, in a real-time simulation? How can I calculate the original distance from the eye-point ?

glReadPixels to a PBO should be fast (it’s a copy within GPU memory), See the “postProcessGL” sample in the SDK (although this just reads color).

So when I use a own Framebuffer for depthbuffer, can I use the followin Code in host:

glGenFramebuffersEXT(1, &fbo);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

glGenRenderbuffersEXT(1, &depthBuffer);

glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);

glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);

glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,

	GL_RENDERBUFFER_EXT, depthBuffer);

cutilSafeCall(cudaGraphicsGLRegisterImage(&cuda_depthBuffer, depthBuffer, 

	GL_TEXTURE_2D, cudaGraphicsMapFlagsReadOnly));

and put in a

texture<uchar3, 2, cudaReadModeElementType> depthTex;

But I got an compiler error when I use the sampler:

uchar3 temp = tex2D(depthTex, 0.0f, 0.0f);

Would this conversion be the correct one to get the exact depth value out of the 24bit integer buffer ?

uchar3 depthUC;

int depthI = depthUC.x*256*256+depthUC.y*256 + depthUC.z;

float depthF = nearClippingPlane + (farClippingPlane-nearClippingPlane)* (depthI/256*256*256)

It’s just a guess.

Might it be correct ?

Or could you just figure out how, you would get and store the depthbuffer with glReadPixels ?

No I tried the follows:

Creating a PBO:

int num_texels = width * height;

int num_values = num_texels;

int size_tex_data = sizeof(GLfloat) * num_values;

void *data = malloc(size_tex_data);

glGenBuffers(1, &depthBuffer);

glBindBuffer(GL_ARRAY_BUFFER, depthBuffer);

glBufferData(GL_ARRAY_BUFFER, size_tex_data, data, GL_DYNAMIC_DRAW);

free(data);

glBindBuffer(GL_ARRAY_BUFFER, 0);

// register this buffer object with CUDA

cutilSafeCall(cudaGraphicsGLRegisterBuffer(&cuda_depthBuffer, depthBuffer, cudaGraphicsMapFlagsNone));

Getting the depthbuffer and map it for CUDA:

glBindBuffer(GL_PIXEL_PACK_BUFFER, depthBuffer);

glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, 0);

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, depthBuffer);

cutilSafeCall(cudaGraphicsMapResources(1, &cuda_depthBuffer, 0));

size_t num_bytes_depth; 

cutilSafeCall(cudaGraphicsResourceGetMappedPointer((void **)&depth_array,  &num_bytes_depth, cuda_depthBuffer));

...

cudacall

...

cutilSafeCall(cudaGraphicsUnmapResources(1, &cuda_depthBuffer, 0));

The Kernel puts it into a texture:

texture<float, 2, cudaReadModeElementType> depthTex;

struct cudaChannelFormatDesc desc;

cutilSafeCall(cudaBindTextureToArray(depthTex, depth_array));

cutilSafeCall(cudaGetChannelDesc(&desc, depth_array));

This works fine by the first call. At the second I get an error:

at:

cutilSafeCall(cudaGraphicsMapResources(1, &cuda_depthBuffer, 0));

Does someone know why, and can someone give me a hint how I can reach my goal ?

Thanks

uchar3 is not a valid texture format - we don’t support any 3-component formats.

You might want to try using this format when creating your render buffer, and then reading it as a uchar4:

http://www.nvidia.com/dev_content/nvopenglspecs/GL_NV_packed_depth_stencil.txt

To be honest I’m not sure if this supported by our interop code. If it doesn’t work I would recommend trying glReadPixels into a PBO as I suggested before.