Cuda et OpenGL Interop
J'ai lu à travers le CUDA de la documentation et il me semble que chaque mémoire tampon qui sert d'interface avec OpenGL doit être créé dans le glBuffer.
Selon la nvidia guide de programmation, ce qui doit être fait comme ceci:
GLuint positionsVBO;
struct cudaGraphicsResource* positionsVBO_CUDA;
int main() {
//Explicitly set device
cudaGLSetGLDevice(0);
//Initialize OpenGL and GLUT
...
glutDisplayFunc(display);
//Create buffer object and register it with CUDA
glGenBuffers(1, positionsVBO);
glBindBuffer(GL_ARRAY_BUFFER, &vbo);
unsigned int size = width * height * 4 * sizeof(float);
glBufferData(GL_ARRAY_BUFFER, size, 0, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
cudaGraphicsGLRegisterBuffer(&positionsVBO_CUDA, positionsVBO, cudaGraphicsMapFlagsWriteDiscard);
//Launch rendering loop
glutMainLoop();
}
void display() {
//Map buffer object for writing from CUDA
float4* positions;
cudaGraphicsMapResources(1, &positionsVBO_CUDA, 0);
size_t num_bytes;
cudaGraphicsResourceGetMappedPointer((void**)&positions, &num_bytes, positionsVBO_CUDA));
//Execute kernel
dim3 dimBlock(16, 16, 1);
dim3 dimGrid(width / dimBlock.x, height / dimBlock.y, 1);
createVertices<<<dimGrid, dimBlock>>>(positions, time, width, height);
//Unmap buffer object
cudaGraphicsUnmapResources(1, &positionsVBO_CUDA, 0);
//Render from buffer object
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, positionsVBO);
glVertexPointer(4, GL_FLOAT, 0, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_POINTS, 0, width * height);
glDisableClientState(GL_VERTEX_ARRAY);
//Swap buffers
glutSwapBuffers();
glutPostRedisplay();
}
void deleteVBO() {
cudaGraphicsUnregisterResource(positionsVBO_CUDA);
glDeleteBuffers(1, &positionsVBO);
}
__global__ void createVertices(float4* positions, float time, unsigned int width, unsigned int height) {
//[....]
}
Est-il un moyen de donner le cudaMalloc créé de l'espace mémoire directement à OpenGL? J'ai déjà travailler le code écrit sur cuda et je veux mettre mon float4 tableau directement dans OpenGL.
Dire si avez déjà un code comme:
float4 *cd = (float4*) cudaMalloc(elements*sizeof(float4)).
do_something<<<16,1>>>(cd);
Et je voulais afficher la sortie de faire_quelque_chose grâce à OpenGL.
Note de côté: pourquoi le cudaGraphicsResourceGetMappedPointer fonction exécuter sur chaque timestep?
Vous devez vous connecter pour publier un commentaire.
De CUDA 4.0, OpenGL interop est un moyen. Que signifie faire ce que vous voulez (exécuter un CUDA noyau qui écrit des données dans un GL de tampon ou de la texture de l'image), vous devez mapper la mémoire tampon d'un dispositif de pointeur, et passez le pointeur de votre noyau, comme indiqué dans votre exemple.
Que, de votre côté remarque: cudaGraphicsResourceGetMappedPointer est appelée à chaque affichage de l'heure() est appelé, car cudaGraphicsMapResource est appelée à chaque image. Toutes les fois que vous re-mapper une ressource, vous devez obtenir le mappé pointeur, car elle peut avoir changé. Pourquoi re-mapper chaque image? Eh bien, OpenGL se déplace parfois tampon les objets dans la mémoire, pour des raisons de performances (en particulier dans beaucoup de mémoire GL applications). Si vous laissez la ressource mappé tout le temps, il ne peut pas le faire, et les performances peuvent en souffrir. Je crois GL capacité et besoin de virtualiser les objets de la mémoire est aussi une des raisons de l'actuelle GL interop API est une façon (le GL n'est pas autorisé à se déplacer CUDA allocations autour, et, par conséquent, vous ne pouvez pas mapper un CUDA-alloués dispositif de pointeur dans un GL buffer object).
Pour un exemple d'utilisation de CUDA-GL interop sans avoir à re-map de toutes les images, veuillez vous référer à cet exemple:
https://github.com/nvpro-samples/gl_cuda_interop_pingpong_st