PDA

View Full Version : pass array into shader



pilot117
01-03-2011, 10:54 PM
hi,

what are the good ways to pass a large array (obtained by cuda code) to fragment/vertex shader?

thanks

aqnuep
01-04-2011, 01:28 AM
If I understand correctly, you want to pass the data generated to a buffer using cuda code to the fragment/vertex shader.

I would recommend using uniform buffers or texture buffers. The former provides usually faster access, the later provides much larger storage.

pilot117
01-04-2011, 10:49 AM
so uniform data are allocated to shared memory from cuda point of view?

I have tried set a large uniform array and copy to it, but it does not work.

So binding texture is the only way? I prefer something like "cudaMemcpy" to pass the data to the shader...

Alfonse Reinheart
01-04-2011, 11:11 AM
so uniform data are allocated to shared memory from cuda point of view?

No, he said uniform buffers (http://www.opengl.org/wiki/Uniform_Buffer_Object).


I prefer something like "cudaMemcpy" to pass the data to the shader...

But using the buffer as a buffer texture or a uniform buffer doesn't involve a memory copy. You just use CUDA to write directly to the buffer, then use the buffer as a uniform buffer or a buffer texture and read from your shader.

kRogue
01-05-2011, 05:28 AM
One thing worth thinking about: since you are using CUDA, it means you are using NVIDIA hardware... so I strongly suggest you look into GL_NV_shader_buffer_load. The basic setup you would have is the following:

Create buffer object so that CUDA and GL can share it.
Let CUDA do it's thing
API calls to let GL use the buffer object
Use GL_NV_shader_buffer_load to access buffer object contents from shader..

Looking at http://developer.download.nvidia.com/compute/cuda/2_3/toolkit/docs/online/group__CUDART__OPENGL.html it looks like one does this:




initBO(void)
{
/*-- create GL buffer object -- */
glGenBuffers();
glBindBuffer();
glBufferData();

/** --register to CUDA --*/
cudaGLRegisterBufferObject();
}

void
computeToBO(void)
{
/* -- map buffer object to CUDA */
cudaGLMapBufferObject();

/* CUDA call to compute */
CUDAComputeBaby();

/* unmap buffer object from CUDA*/
cudaGLUnmapBufferObject();
}

void
useBO(void)
{
//use buffer object freely in GL... the best one if by far to
//fetch the Buffer objects GPU address and use that value as a uniform,
//see GL_NV_shader_buffer_load.

}

void
whatever(void)
{
init_CUDA();

initBO();
while(keep_render_bender)
{
computeToBO();
useBO();
}
}


naturally, likely you will want to have 2 buffer objects flying around, one where you compute to, and the other that you use to render from and swapping between the two.

Since you are using CUDA, I strongly recommend that you also use GL_NV_shader_buffer_load, as it allows much more flexible and natural access to the buffer object data... binding the buffer object to a uniform (known as uniform buffer objects and bindable uniforms) has size limitations and texture buffer objects (i.e. a buffer object becomes the data source for a large array) forces one to have that the data is just an array of simple data types: AvecN where A=float, int8, int16, int32, uint8, uint16 or uint32 and N=1,2 or 4 (GeForce 4xx cards support N=3 though).

pilot117
01-05-2011, 10:22 AM
hey, guys, got plenty stuff here! many thanks for these information!